From: Sandro Santilli Date: Thu, 18 Nov 2004 18:14:19 +0000 (+0000) Subject: Added a copy of the PQunescapeBytea function found in libpq of PG>=73 X-Git-Tag: pgis_1_0_0RC1~193 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=356c91a09fbaf855d794f08d4abdcf2ffa453fdb;p=postgis Added a copy of the PQunescapeBytea function found in libpq of PG>=73 git-svn-id: http://svn.osgeo.org/postgis/trunk@1102 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/loader/Makefile b/loader/Makefile index 37444054f..54b4a304f 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -12,7 +12,7 @@ ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) EXE = .exe endif -OBJS = shpopen.o dbfopen.o getopt.o +OBJS = shpopen.o dbfopen.o getopt.o PQunescapeBytea.o #--------------------------------------------------------------- diff --git a/loader/PQunescapeBytea.c b/loader/PQunescapeBytea.c new file mode 100644 index 000000000..05fdc7adc --- /dev/null +++ b/loader/PQunescapeBytea.c @@ -0,0 +1,110 @@ +/*************************************************************************** + * This has been copied from: + * PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v + * 1.165 2004/10/21 19:28:36 tgl Exp + * + * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + **************************************************************************/ + +#include +#include +#include +#include "compat.h" + +#if USE_VERSION < 73 + +#define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3') +#define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7') +#define OCTVAL(CH) ((CH) - '0') + +/* + * PQunescapeBytea - converts the null terminated string representation + * of a bytea, strtext, into binary, filling a buffer. It returns a + * pointer to the buffer (or NULL on error), and the size of the + * buffer in retbuflen. The pointer may subsequently be used as an + * argument to the function free(3). It is the reverse of PQescapeBytea. + * + * The following transformations are made: + * \\ == ASCII 92 == \ + * \ooo == a byte whose value = ooo (ooo is an octal number) + * \x == x (x is any character not matched by the above transformations) + */ +unsigned char * +PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen) +{ + size_t strtextlen, + buflen; + unsigned char *buffer, + *tmpbuf; + size_t i, + j; + + if (strtext == NULL) + return NULL; + + strtextlen = strlen(strtext); + + /* + * Length of input is max length of output, but add one to avoid + * unportable malloc(0) if input is zero-length. + */ + buffer = (unsigned char *) malloc(strtextlen + 1); + if (buffer == NULL) + return NULL; + + for (i = j = 0; i < strtextlen;) + { + switch (strtext[i]) + { + case '\\': + i++; + if (strtext[i] == '\\') + buffer[j++] = strtext[i++]; + else + { + if ((ISFIRSTOCTDIGIT(strtext[i])) && + (ISOCTDIGIT(strtext[i + 1])) && + (ISOCTDIGIT(strtext[i + 2]))) + { + int byte; + + byte = OCTVAL(strtext[i++]); + byte = (byte << 3) + OCTVAL(strtext[i++]); + byte = (byte << 3) + OCTVAL(strtext[i++]); + buffer[j++] = byte; + } + } + + /* + * Note: if we see '\' followed by something that isn't a + * recognized escape sequence, we loop around having done + * nothing except advance i. Therefore the something will + * be emitted as ordinary data on the next cycle. Corner + * case: '\' at end of string will just be discarded. + */ + break; + + default: + buffer[j++] = strtext[i++]; + break; + } + } + buflen = j; /* buflen is the length of the dequoted + * data */ + + /* Shrink the buffer to be no larger than necessary */ + /* +1 avoids unportable behavior when buflen==0 */ + tmpbuf = realloc(buffer, buflen + 1); + + /* It would only be a very brain-dead realloc that could fail, but... */ + if (!tmpbuf) + { + free(buffer); + return NULL; + } + + *retbuflen = buflen; + return tmpbuf; +} +#endif // USE_VERSION < 73 diff --git a/loader/compat.h b/loader/compat.h new file mode 100644 index 000000000..3955cfaf6 --- /dev/null +++ b/loader/compat.h @@ -0,0 +1,12 @@ +#ifndef _COMPAT_H +#define _COMPAT_H 1 + +#include +#include +#include + +#if USE_VERSION < 73 +unsigned char *PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen); +#endif + +#endif // ifndef _COMPAT_H diff --git a/loader/pgsql2shp.c b/loader/pgsql2shp.c index 065b9ee22..ffaf0d087 100644 --- a/loader/pgsql2shp.c +++ b/loader/pgsql2shp.c @@ -26,6 +26,7 @@ static char rcsid[] = #include "libpq-fe.h" #include "shapefil.h" #include "getopt.h" +#include "compat.h" #ifdef __CYGWIN__ #include @@ -48,7 +49,7 @@ static char rcsid[] = #define VERBOSE 1 /* Define this to use HEX encoding instead of bytea encoding */ -#define HEXWKB +#define HEXWKB 1 typedef unsigned long int uint32; typedef unsigned char byte; @@ -3086,6 +3087,9 @@ create_usrquerytable() /********************************************************************** * $Log$ + * Revision 1.68 2004/11/18 18:14:19 strk + * Added a copy of the PQunescapeBytea function found in libpq of PG>=73 + * * Revision 1.67 2004/10/17 12:16:47 strk * fixed prototype for user query table *