Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)