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">
@ -955,6 +955,25 @@ strings overlap.
byte is also added. The single quotes that must surround
PostgreSQL string literals are not part of the result string.
</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>

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 $
*
*-------------------------------------------------------------------------
*/
@ -15,27 +15,28 @@
#define ELOG_H
/* Error level codes */
#define DEBUG5 10 /* Debugging messages, in categories
* of decreasing detail. */
#define DEBUG4 11
#define DEBUG3 12
#define DEBUG2 13
#define DEBUG1 14
#define LOG 15 /* Server operational history messages;
* sent only to server log by default. */
#define COMMERROR 16 /* Client communication problems; same as
* LOG for server reporting, but never ever
* try to send to client. */
#define INFO 17 /* Informative messages that are part of
* normal query operation; sent only to
* client by default. */
#define NOTICE 18 /* Important messages, for unusual cases that
* should be reported but are not serious
* enough to abort the query. Sent to client
* and server log by default. */
#define ERROR 19 /* user error - return to known state */
#define FATAL 20 /* fatal error - abort process */
#define PANIC 21 /* take down the other backends with me */
#define DEBUG5 10 /* Debugging messages, in categories
* of decreasing detail. */
#define DEBUG4 11
#define DEBUG3 12
#define DEBUG2 13
#define DEBUG1 14
#define LOG 15 /* Server operational history messages;
* sent only to server log by default. */
#define COMMERROR 16 /* Client communication problems; same as
* LOG for server reporting, but never ever
* try to send to client. */
#define INFO 17 /* Informative messages that are part of
* normal query operation; sent only to
* client by default. */
#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
* enough to abort the query. Sent to client
* and server log by default. */
#define ERROR 20 /* user error - return to known state */
#define FATAL 21 /* fatal error - abort process */
#define PANIC 22 /* take down the other backends with me */
/*#define DEBUG DEBUG1*/ /* Backward compatibility with pre-7.3 */

View File

@ -8,7 +8,7 @@
*
*
* 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;
}
/*
* 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.
*

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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 unsigned char *PQescapeBytea(unsigned char *bintext, size_t binlen,
size_t *bytealen);
extern unsigned char *PQunescapeBytea(unsigned char *strtext,
size_t *retbuflen);
/* Simple synchronous query */
extern PGresult *PQexec(PGconn *conn, const char *query);