Commit 294f0d4b authored by Bruce Momjian's avatar Bruce Momjian

Add PQunescapeBytea libpq function.

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

Patrick Welche
parent b2aade0e
<!-- <!--
$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. ...@@ -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>
......
...@@ -7,7 +7,7 @@ ...@@ -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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -15,27 +15,28 @@ ...@@ -15,27 +15,28 @@
#define ELOG_H #define ELOG_H
/* Error level codes */ /* Error level codes */
#define DEBUG5 10 /* Debugging messages, in categories #define DEBUG5 10 /* Debugging messages, in categories
* of decreasing detail. */ * of decreasing detail. */
#define DEBUG4 11 #define DEBUG4 11
#define DEBUG3 12 #define DEBUG3 12
#define DEBUG2 13 #define DEBUG2 13
#define DEBUG1 14 #define DEBUG1 14
#define LOG 15 /* Server operational history messages; #define LOG 15 /* Server operational history messages;
* sent only to server log by default. */ * sent only to server log by default. */
#define COMMERROR 16 /* Client communication problems; same as #define COMMERROR 16 /* Client communication problems; same as
* LOG for server reporting, but never ever * LOG for server reporting, but never ever
* try to send to client. */ * try to send to client. */
#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 */
* should be reported but are not serious #define NOTICE 19 /* Important messages, for unusual cases that
* enough to abort the query. Sent to client * should be reported but are not serious
* and server log by default. */ * enough to abort the query. Sent to client
#define ERROR 19 /* user error - return to known state */ * and server log by default. */
#define FATAL 20 /* fatal error - abort process */ #define ERROR 20 /* user error - return to known state */
#define PANIC 21 /* take down the other backends with me */ #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 */ /*#define DEBUG DEBUG1*/ /* Backward compatibility with pre-7.3 */
......
...@@ -8,7 +8,7 @@ ...@@ -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) ...@@ -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.
* *
......
...@@ -7,7 +7,7 @@ ...@@ -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, ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment