mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-01 19:45:33 +08:00
Add PQunescapeBytea libpq function.
Everyone using libpq and bytea is probably having to invent this wheel.. Patrick Welche
This commit is contained in:
parent
b2aade0e4b
commit
294f0d4bd6
@ -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>
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user