Add PQunescapeBytea libpq function.
authorBruce Momjian
Mon, 4 Mar 2002 23:59:14 +0000 (23:59 +0000)
committerBruce Momjian
Mon, 4 Mar 2002 23:59:14 +0000 (23:59 +0000)
Everyone using libpq and bytea is probably having to invent this wheel..

Patrick Welche

doc/src/sgml/libpq.sgml
src/include/utils/elog.h
src/interfaces/libpq/fe-exec.c
src/interfaces/libpq/libpq-fe.h

index d487cce5cc30b339d42b9bb640e02222c49a034f..34ab2bb59f85042ce4c8177e590a160bce93ed92 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -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.
   
+
+  
+   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).
+  
+   
  
 
 
index 0b72865e39da9f490878edcc83d5b98ebef72a49..2d8dc4ea5c217da2fef74235aeeea1637b8e4ea2 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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 */
 
index 123d7abd1296dd25dc51d478add8b7118581b9e3..7eeaefbb55db54eea24122b5dddc78416af1629c 100644 (file)
@@ -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.
  *
index 02dbe104d06414ea58d53795330c2405c21087e8..b94b5aae0acf53515800c23f668de81606c180b6 100644 (file)
@@ -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);