Skip to Content.
Sympa Menu

freetds - RE: [freetds] hard-coded UCS-2 strings and the C standard

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "ZIGLIO, Frediano, VF-IT" <Frediano.Ziglio AT vodafone.com>
  • To: "FreeTDS Development Group" <freetds AT lists.ibiblio.org>
  • Subject: RE: [freetds] hard-coded UCS-2 strings and the C standard
  • Date: Mon, 13 Jun 2005 10:10:01 +0200

>
> Frediano Ziglio wrote:
> > Il giorno ven, 10-06-2005 alle 14:55 -0400, Lowden, James K
> ha scritto:
> > > In src/tds/query.c we have several hard-coded UCS-2 strings e.g.:
> > >
> > > tds_put_n(tds, "s\0p\0_\0c\0u\0r\0s\0o\0r\0c\0l\0o\0s\0e", 28);
> > >
> > > Standard C (C99?) lets this be written as:
> > >
> > > tds_put_n(tds, L"sp_cursorclose", 28);
> > >
> >
> > This is a wide string, not a UCS-2 string. On many Unix
> systems (*BSD,
> > Linux) is encoded in UCS-4, not UCS-2.
> "s\0p\0_\0c\0u\0r\0s\0o\0r\0c\0l
> > \0o\0s\0e" is always UCS2-LE.
>
> Oh. Thanks for the education. :-)
>
> I find the hard-coded strings unpretty and hard to read (and
> scan for).
> So, I wrote the attached patch. It would let us replace:
>
> $ grep put_n *.c |grep s..p.._
> query.c: tds_put_n(tds,
> "s\0p\0_\0e\0x\0e\0c\0u\0t\0e\0s\0q\0l", 26);
> query.c: tds_put_n(tds,
> "s\0p\0_\0p\0r\0e\0p\0a\0r\0e", 20);
> query.c: tds_put_n(tds,
> "s\0p\0_\0e\0x\0e\0c\0u\0t\0e\0s\0q\0l", 26);
> query.c: tds_put_n(tds, "s\0p\0_\0e\0x\0e\0c\0u\0t\0e",
> 20);
> query.c: tds_put_n(tds,
> "s\0p\0_\0u\0n\0p\0r\0e\0p\0a\0r\0e", 24);
> query.c: tds_put_n(tds,
> "s\0p\0_\0c\0u\0r\0s\0o\0r\0o\0p\0e\0n", 26);
> query.c: tds_put_n(tds,
> "s\0p\0_\0c\0u\0r\0s\0o\0r\0f\0e\0t\0c\0h", 28);
> query.c: tds_put_n(tds,
> "s\0p\0_\0c\0u\0r\0s\0o\0r\0c\0l\0o\0s\0e", 28);
>
> with:
>
> $ grep put_n *.c |grep s..p.._ \
> |sed 's/, 2[0-9]//;s/tds_put_n/&_as_UCS2/;s:\\0::g'
> query.c: tds_put_n_as_UCS2(tds,
> "sp_executesql");
> query.c: tds_put_n_as_UCS2(tds, "sp_prepare");
> query.c: tds_put_n_as_UCS2(tds,
> "sp_executesql");
> query.c: tds_put_n_as_UCS2(tds, "sp_execute");
> query.c: tds_put_n_as_UCS2(tds,
> "sp_unprepare");
> query.c: tds_put_n_as_UCS2(tds,
> "sp_cursoropen");
> query.c: tds_put_n_as_UCS2(tds,
> "sp_cursorfetch");
> query.c: tds_put_n_as_UCS2(tds,
> "sp_cursorclose");
>
> What do you think?
>

tds_put_string should work too but it expect client encoding... another
solution is to separate code to handle iso -> ucs2 conversion. It seems
that iso2server_metadata conversion is used only to do this conversion,
perhaps a tds_iso2ucs2le would eliminate the need for this conversion
too

unsigned tds_iso2ucs2le(char *dest, const char *src)
{
char *s = dest;
while(*src) {
*s++ = *src++;
*s++ = 0;
}
return s - dest;
}

in query.c

from

tds_put_n(tds, "s\0p\0_\0e\0x\0e\0c\0u\0t\0e", 20);

to

char buf[50];
tds_put_n(tds, buf, tds_iso2ucs2le(buf, "sp_execute"));

perhaps a define like

#define TDS_PUT_AS_UCS2(tds, s) do { \
char buffer[sizeof(s)*2-2]; \
tds_put_n(tds, buffer, tds_iso2ucs2le(buffer, s)); \
} while(0)

would help too

freddy77




Archive powered by MHonArc 2.6.24.

Top of Page