Everyone using libpq and bytea is probably having to invent this wheel..
Patrick Welche
byte is also added. The single quotes that must surround
PostgreSQL string literals are not part of the result string.
+
+ PQunescapeBytea
+ Converts an escaped string representation of binary data into binary
+ data - the reverse of PQescapeBytea.
+
+ unsigned char *PQunescapeBytea(unsigned char *from, size_t *to_length);
+
+
+ The
from parameter points to an escaped string
+ such as might be returned by PQgetvalue of a
+ BYTEA column. PQunescapeBytea 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
to_length. The pointer may
+ subsequently be used as an argument to the function
+ free(3).
+
+
* 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 $
*
*-------------------------------------------------------------------------
*/
#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 */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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.
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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);