Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 294f0d4

Browse files
committed
Add PQunescapeBytea libpq function.
Everyone using libpq and bytea is probably having to invent this wheel.. Patrick Welche
1 parent b2aade0 commit 294f0d4

File tree

4 files changed

+137
-25
lines changed

4 files changed

+137
-25
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.87 2002/01/18 20:39:04 momjian Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.88 2002/03/04 23:59:11 momjian Exp $
33
-->
44

55
<chapter id="libpq">
@@ -955,6 +955,25 @@ strings overlap.
955955
byte is also added. The single quotes that must surround
956956
PostgreSQL string literals are not part of the result string.
957957
</para>
958+
959+
<para>
960+
<function>PQunescapeBytea</function>
961+
Converts an escaped string representation of binary data into binary
962+
data - the reverse of <function>PQescapeBytea</function>.
963+
<synopsis>
964+
unsigned char *PQunescapeBytea(unsigned char *from, size_t *to_length);
965+
</synopsis>
966+
967+
The <paramater>from</parameter> parameter points to an escaped string
968+
such as might be returned by <function>PQgetvalue</function> of a
969+
<type>BYTEA</type> column. <function>PQunescapeBytea</function> converts
970+
this NUL terminated string representation into binary, filling a buffer.
971+
It returns a pointer to the buffer which is NULL on error, and the size
972+
of the buffer in <parameter>to_length</parameter>. The pointer may
973+
subsequently be used as an argument to the function
974+
<function>free(3)</function>.
975+
</para>
976+
958977
</sect2>
959978

960979

src/include/utils/elog.h

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,36 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: elog.h,v 1.32 2002/03/04 01:46:04 tgl Exp $
10+
* $Id: elog.h,v 1.33 2002/03/04 23:59:14 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
1414
#ifndef ELOG_H
1515
#define ELOG_H
1616

1717
/* Error level codes */
18-
#define DEBUG5 10 /* Debugging messages, in categories
19-
* of decreasing detail. */
20-
#define DEBUG4 11
21-
#define DEBUG3 12
22-
#define DEBUG2 13
23-
#define DEBUG1 14
24-
#define LOG 15 /* Server operational history messages;
25-
* sent only to server log by default. */
26-
#define COMMERROR 16 /* Client communication problems; same as
27-
* LOG for server reporting, but never ever
28-
* try to send to client. */
29-
#define INFO 17 /* Informative messages that are part of
30-
* normal query operation; sent only to
31-
* client by default. */
32-
#define NOTICE 18 /* Important messages, for unusual cases that
33-
* should be reported but are not serious
34-
* enough to abort the query. Sent to client
35-
* and server log by default. */
36-
#define ERROR 19 /* user error - return to known state */
37-
#define FATAL 20 /* fatal error - abort process */
38-
#define PANIC 21 /* take down the other backends with me */
18+
#define DEBUG5 10 /* Debugging messages, in categories
19+
* of decreasing detail. */
20+
#define DEBUG4 11
21+
#define DEBUG3 12
22+
#define DEBUG2 13
23+
#define DEBUG1 14
24+
#define LOG 15 /* Server operational history messages;
25+
* sent only to server log by default. */
26+
#define COMMERROR 16 /* Client communication problems; same as
27+
* LOG for server reporting, but never ever
28+
* try to send to client. */
29+
#define INFO 17 /* Informative messages that are part of
30+
* normal query operation; sent only to
31+
* client by default. */
32+
#define INFOALWAYS 18 /* Like INFO, but always prints to client */
33+
#define NOTICE 19 /* Important messages, for unusual cases that
34+
* should be reported but are not serious
35+
* enough to abort the query. Sent to client
36+
* and server log by default. */
37+
#define ERROR 20 /* user error - return to known state */
38+
#define FATAL 21 /* fatal error - abort process */
39+
#define PANIC 22 /* take down the other backends with me */
3940

4041
/*#define DEBUG DEBUG1*/ /* Backward compatibility with pre-7.3 */
4142

src/interfaces/libpq/fe-exec.c

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.113 2001/10/25 05:50:13 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.114 2002/03/04 23:59:14 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -180,6 +180,95 @@ PQescapeBytea(unsigned char *bintext, size_t binlen, size_t *bytealen)
180180
return result;
181181
}
182182

183+
/*
184+
* PQunescapeBytea - converts the null terminated string representation
185+
* of a bytea, strtext, into binary, filling a buffer. It returns a
186+
* pointer to the buffer which is NULL on error, and the size of the
187+
* buffer in retbuflen. The pointer may subsequently be used as an
188+
* argument to the function free(3). It is the reverse of PQescapeBytea.
189+
*
190+
* The following transformations are reversed:
191+
* '\0' == ASCII 0 == \000
192+
* '\'' == ASCII 39 == \'
193+
* '\\' == ASCII 92 == \\
194+
*
195+
* States:
196+
* 0 normal 0->1->2->3->4
197+
* 1 \ 1->5
198+
* 2 \0 1->6
199+
* 3 \00
200+
* 4 \000
201+
* 5 \'
202+
* 6 \\
203+
*/
204+
unsigned char *
205+
PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
206+
{
207+
size_t buflen;
208+
unsigned char *buffer, *sp, *bp;
209+
unsigned int state=0;
210+
211+
if(strtext == NULL)return NULL;
212+
buflen = strlen(strtext); /* will shrink, also we discover if strtext */
213+
buffer = (unsigned char *) malloc(buflen); /* isn't NULL terminated */
214+
if(buffer == NULL)return NULL;
215+
for(bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++)
216+
{
217+
switch(state)
218+
{
219+
case 0:
220+
if(*sp == '\\')state=1;
221+
*bp = *sp;
222+
break;
223+
case 1:
224+
if(*sp == '\'') /* state=5 */
225+
{ /* replace \' with 39 */
226+
bp--;
227+
*bp = 39;
228+
buflen--;
229+
state=0;
230+
}
231+
else if(*sp == '\\') /* state=6 */
232+
{ /* replace \\ with 92 */
233+
bp--;
234+
*bp = 92;
235+
buflen--;
236+
state=0;
237+
}
238+
else
239+
{
240+
if(*sp == '0')state=2;
241+
else state=0;
242+
*bp = *sp;
243+
}
244+
break;
245+
case 2:
246+
if(*sp == '0')state=3;
247+
else state=0;
248+
*bp = *sp;
249+
break;
250+
case 3:
251+
if(*sp == '0') /* state=4 */
252+
{
253+
bp -= 3;
254+
*bp = 0;
255+
buflen -= 3;
256+
state=0;
257+
}
258+
else
259+
{
260+
*bp = *sp;
261+
state=0;
262+
}
263+
break;
264+
}
265+
}
266+
realloc(buffer,buflen);
267+
268+
*retbuflen=buflen;
269+
return buffer;
270+
}
271+
183272
/* ----------------
184273
* Space management for PGresult.
185274
*

src/interfaces/libpq/libpq-fe.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: libpq-fe.h,v 1.80 2001/11/08 20:37:52 momjian Exp $
10+
* $Id: libpq-fe.h,v 1.81 2002/03/04 23:59:14 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -252,6 +252,9 @@ extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn,
252252
extern size_t PQescapeString(char *to, const char *from, size_t length);
253253
extern unsigned char *PQescapeBytea(unsigned char *bintext, size_t binlen,
254254
size_t *bytealen);
255+
extern unsigned char *PQunescapeBytea(unsigned char *strtext,
256+
size_t *retbuflen);
257+
255258

256259
/* Simple synchronous query */
257260
extern PGresult *PQexec(PGconn *conn, const char *query);

0 commit comments

Comments
 (0)