Add PQunescapeBytea libpq function.

Everyone using libpq and bytea is probably having to invent this wheel..

Patrick Welche
This commit is contained in:
Bruce Momjian 2002-03-04 23:59:14 +00:00
parent b2aade0e4b
commit 294f0d4bd6
4 changed files with 137 additions and 25 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.87 2002/01/18 20:39:04 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.88 2002/03/04 23:59:11 momjian Exp $
--> -->
<chapter id="libpq"> <chapter id="libpq">
@ -955,6 +955,25 @@ strings overlap.
byte is also added. The single quotes that must surround byte is also added. The single quotes that must surround
PostgreSQL string literals are not part of the result string. PostgreSQL string literals are not part of the result string.
</para> </para>
<para>
<function>PQunescapeBytea</function>
Converts an escaped string representation of binary data into binary
data - the reverse of <function>PQescapeBytea</function>.
<synopsis>
unsigned char *PQunescapeBytea(unsigned char *from, size_t *to_length);
</synopsis>
The <paramater>from</parameter> parameter points to an escaped string
such as might be returned by <function>PQgetvalue</function> of a
<type>BYTEA</type> column. <function>PQunescapeBytea</function> converts
this NUL terminated string representation into binary, filling a buffer.
It returns a pointer to the buffer which is NULL on error, and the size
of the buffer in <parameter>to_length</parameter>. The pointer may
subsequently be used as an argument to the function
<function>free(3)</function>.
</para>
</sect2> </sect2>

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: elog.h,v 1.32 2002/03/04 01:46:04 tgl Exp $ * $Id: elog.h,v 1.33 2002/03/04 23:59:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -29,13 +29,14 @@
#define INFO 17 /* Informative messages that are part of #define INFO 17 /* Informative messages that are part of
* normal query operation; sent only to * normal query operation; sent only to
* client by default. */ * client by default. */
#define NOTICE 18 /* Important messages, for unusual cases that #define INFOALWAYS 18 /* Like INFO, but always prints to client */
#define NOTICE 19 /* Important messages, for unusual cases that
* should be reported but are not serious * should be reported but are not serious
* enough to abort the query. Sent to client * enough to abort the query. Sent to client
* and server log by default. */ * and server log by default. */
#define ERROR 19 /* user error - return to known state */ #define ERROR 20 /* user error - return to known state */
#define FATAL 20 /* fatal error - abort process */ #define FATAL 21 /* fatal error - abort process */
#define PANIC 21 /* take down the other backends with me */ #define PANIC 22 /* take down the other backends with me */
/*#define DEBUG DEBUG1*/ /* Backward compatibility with pre-7.3 */ /*#define DEBUG DEBUG1*/ /* Backward compatibility with pre-7.3 */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.113 2001/10/25 05:50:13 momjian Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.114 2002/03/04 23:59:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -180,6 +180,95 @@ PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
return result; return result;
} }
/*
* PQunescapeBytea - converts the null terminated string representation
* of a bytea, strtext, into binary, filling a buffer. It returns a
* pointer to the buffer which is 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 reversed:
* '\0' == ASCII 0 == \000
* '\'' == ASCII 39 == \'
* '\\' == ASCII 92 == \\
*
* States:
* 0 normal 0->1->2->3->4
* 1 \ 1->5
* 2 \0 1->6
* 3 \00
* 4 \000
* 5 \'
* 6 \\
*/
unsigned char *
PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
{
size_t buflen;
unsigned char *buffer, *sp, *bp;
unsigned int state=0;
if(strtext == NULL)return NULL;
buflen = strlen(strtext); /* will shrink, also we discover if strtext */
buffer = (unsigned char *) malloc(buflen); /* isn't NULL terminated */
if(buffer == NULL)return NULL;
for(bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++)
{
switch(state)
{
case 0:
if(*sp == '\\')state=1;
*bp = *sp;
break;
case 1:
if(*sp == '\'') /* state=5 */
{ /* replace \' with 39 */
bp--;
*bp = 39;
buflen--;
state=0;
}
else if(*sp == '\\') /* state=6 */
{ /* replace \\ with 92 */
bp--;
*bp = 92;
buflen--;
state=0;
}
else
{
if(*sp == '0')state=2;
else state=0;
*bp = *sp;
}
break;
case 2:
if(*sp == '0')state=3;
else state=0;
*bp = *sp;
break;
case 3:
if(*sp == '0') /* state=4 */
{
bp -= 3;
*bp = 0;
buflen -= 3;
state=0;
}
else
{
*bp = *sp;
state=0;
}
break;
}
}
realloc(buffer,buflen);
*retbuflen=buflen;
return buffer;
}
/* ---------------- /* ----------------
* Space management for PGresult. * Space management for PGresult.
* *

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpq-fe.h,v 1.80 2001/11/08 20:37:52 momjian Exp $ * $Id: libpq-fe.h,v 1.81 2002/03/04 23:59:14 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -252,6 +252,9 @@ extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn,
extern size_t PQescapeString(char *to, const char *from, size_t length); extern size_t PQescapeString(char *to, const char *from, size_t length);
extern unsigned char *PQescapeBytea(unsigned char *bintext, size_t binlen, extern unsigned char *PQescapeBytea(unsigned char *bintext, size_t binlen,
size_t *bytealen); size_t *bytealen);
extern unsigned char *PQunescapeBytea(unsigned char *strtext,
size_t *retbuflen);
/* Simple synchronous query */ /* Simple synchronous query */
extern PGresult *PQexec(PGconn *conn, const char *query); extern PGresult *PQexec(PGconn *conn, const char *query);