Skip to Content.
Sympa Menu

freetds - Re: NTEXT support (again)

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Bob Kline <bkline AT rksystems.com>
  • To: TDS Development Group <freetds AT franklin.oit.unc.edu>
  • Subject: Re: NTEXT support (again)
  • Date: Sun, 4 Jun 2000 09:10:06 -0400 (EDT)


On Sat, 3 Jun 2000, Bob Kline wrote:

> At the risk of making a pest of myself, I'm going to ask once again for
> a little more clarification on the state of affairs on the TDS 7.0
> support, specifically for working with NTEXT columns. [blah, blah,
> blah ...]

I'm replying to my own message. I dug into the sources and figured out
how to modify them so I could retrieve data from NTEXT columns. I tried
to check out the latest sources from the CVS repository using the
anonymous login instructions in the FAQ, but it didn't work:

cvs [checkout aborted]: authorization failed: server \
freetds.internetcds.com rejected access

So I made a set of diffs against the 0.50 sources. This doesn't address
updating of data, and you can see from the comments that there are some
loose ends which I'm carrying on from the base code (like the hard-wired
limit of 255 for (var)char conversions and the fact that the upper
layers (dblib anyway) aren't calculating the source length for
wide-character strings correctly). I tried to emulate what I determined
was the most prevalent of the tabbing/indenting styles in the original
code. I used my own typedef for the wide characters (utf16_t) because
the gcc wchar_t is 4 bytes wide (which is a bit odd, as wcslen does the
right thing with the 16-bit characters). I added an assert to check the
width of the utf16_t, because this will break if unsigned short ever
gets bigger than two bytes. It may be that an integral type shouldn't
be used at all, if the characters are always sent in the same endian
order (anybody know?), and narrowing should always grab the first byte.
I wouldn't put it past Microsoft.

Hope this is useful.

*** tds.h.orig Tue Nov 30 22:20:33 1999
--- tds.h Sun Jun 4 08:24:39 2000
***************
*** 155,160 ****
--- 155,161 ----
#define SYBDATETIME 61 /* 0x3D */
#define SYBBIT 50 /* 0x32 */
#define SYBTEXT 35 /* 0x23 */
+ #define SYBNTEXT 99 /* 0x63 */
#define SYBIMAGE 34 /* 0x22 */
#define SYBMONEY4 122 /* 0x7A */
#define SYBMONEY 60 /* 0x3C */
***************
*** 196,203 ****
x==SYBVARBINARY || \
x==SYBMONEYN || \
x==SYBTEXT || \
! x==SYBIMAGE)
! #define is_blob_type(x) (x==SYBTEXT || x==SYBIMAGE)
/* large type means it has a two byte size field */
#define is_large_type(x) (x>128)
#define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL)
--- 197,205 ----
x==SYBVARBINARY || \
x==SYBMONEYN || \
x==SYBTEXT || \
! x==SYBIMAGE || \
! x==SYBNTEXT)
! #define is_blob_type(x) (x==SYBTEXT || x==SYBIMAGE || x==SYBNTEXT)
/* large type means it has a two byte size field */
#define is_large_type(x) (x>128)
#define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL)


*** convert.c.orig Fri Dec 3 20:06:07 1999
--- convert.c Sun Jun 4 08:30:13 2000
***************
*** 23,28 ****
--- 23,29 ----
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
+ #include <assert.h>


static char software_version[] = "$Id: convert.c,v 1.35 1999/12/04
01:06:07 camber Exp $";
***************
*** 103,108 ****
--- 104,157 ----
return cplen;
}
}
+
+ typedef unsigned short utf16_t;
+
+ TDS_INT tds_convert_ntext(int srctype,unsigned char *src,TDS_UINT srclen,
+ int desttype,unsigned char *dest,TDS_UINT destlen)
+ {
+ /*
+ * XXX Should really be fixed at higher levels. If srclen is 1,
+ * it was probably calculated with strlen(), so we don't believe
+ * it and calculate the source length ourselves.
+ * XXX Limit of 255 + 1 needs to be fixed by determining what the
+ * real limit of [N][VAR]CHAR columns is.
+ * XXX What about NCHAR? Don't see a constant for it in tds.h.
+ */
+ TDS_UINT i, cplen, char_limit = 255 + 1;
+ utf16_t* wsrc = (utf16_t*)src;
+ utf16_t* wdest = (utf16_t*)dest;
+ assert(sizeof(utf16_t) == 2);
+ if (srclen < 2)
+ srclen = wcslen(wsrc) * sizeof(utf16_t) + sizeof(utf16_t);
+ switch (desttype) {
+ case SYBNVARCHAR:
+ if (destlen > char_limit * sizeof(utf16_t))
+ destlen = char_limit * sizeof(utf16_t);
+ /* Fall through ... */
+ case SYBNTEXT:
+ cplen = srclen > destlen ? destlen : srclen;
+ memcpy(dest, src, cplen);
+ if (destlen < srclen) {
+ size_t term_pos = destlen - sizeof(utf16_t);
+ size_t odd_bytes = term_pos % sizeof(utf16_t);
+ term_pos -= odd_bytes;
+ wdest[term_pos / sizeof(utf16_t)] = 0;
+ }
+ return wcslen(wdest);
+ default:
+ /* Assume caller wants conversion to narrow string. */
+ if (destlen > char_limit && desttype != SYBTEXT)
+ destlen = char_limit;
+ cplen = srclen > destlen ? destlen : srclen;
+ for (i = 0; i < cplen; ++i)
+ dest[i] = (unsigned char)wsrc[i];
+ if (destlen < srclen)
+ dest[destlen - 1] = 0;
+ return strlen(dest);
+ }
+ }
+
TDS_INT tds_convert_binary(int srctype,unsigned char *src,TDS_INT srclen,
int desttype,unsigned char *dest,TDS_INT destlen)
{
***************
*** 678,683 ****
--- 727,736 ----
break;
case SYBTEXT:
return tds_convert_text(srctype,src,srclen,
+ desttype,dest,destlen);
+ break;
+ case SYBNTEXT:
+ return tds_convert_ntext(srctype,src,srclen,
desttype,dest,destlen);
break;
default:

--
Bob Kline
mailto:bkline AT rksystems.com
http://www.rksystems.com





Archive powered by MHonArc 2.6.24.

Top of Page