<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.0.10">
</HEAD>
<BODY>
Thanks to Kavous Bojnourdi for pointing out that the pg client library has functions that do what I was trying to do - this means more code reuse (which is nice). Here is my version of his version of my patch, with two changes incorporated. Firstly the unnecessary output variable and the memory copying were removed from both functions. Secondly the pgbytea_unescape called Py_BuildValue with an &quot;s&quot;, rather than an &quot;s#&quot; argument, leaving it unable to cope with any &quot;premature&quot; zero bytes, which it would have assumed to be terminators.<BR>
<BR>
Here then is the third revision of the patch - once again thanks to Kavous for his input.<BR>
== CUT ==<BR>
diff -ur PyGreSQL-3.6-pre040830/pgmodule.c PyGreSQL-3.6-pre040830_mod/pgmodule.c<BR>
--- PyGreSQL-3.6-pre040830/pgmodule.c        2004-08-30 09:54:27.000000000 +0100<BR>
+++ PyGreSQL-3.6-pre040830_mod/pgmodule.c        2004-09-09 19:40:50.037533519 +0100<BR>
@@ -1550,6 +1550,48 @@<BR>
 <BR>
         return (PyObject *) npgobj;<BR>
 }<BR>
+static PyObject *pgbytea_escape(PyObject *self, PyObject *args) {<BR>
+        char *str; /* Our argument */<BR>
+        int strlength; /* Length of string */<BR>
+        int tolen=0;<BR>
+        char * tmp;<BR>
+        PyObject *ret; /* String object to return */<BR>
+<BR>
+        if (!PyArg_ParseTuple(args, &quot;s#&quot;, &amp;str, &amp;strlength))<BR>
+                return NULL;<BR>
+<BR>
+        tmp = PQescapeBytea(str,strlength,&amp;tolen);<BR>
+        ret = Py_BuildValue(&quot;s&quot;, tmp);<BR>
+        PQfreemem(tmp);<BR>
+<BR>
+        if(!ret)<BR>
+                /* Pass on exception */<BR>
+                return NULL;<BR>
+<BR>
+        return ret;<BR>
+}<BR>
+<BR>
+static PyObject *pgbytea_unescape(PyObject *self, PyObject *args) {<BR>
+        char *str; /* Our argument */<BR>
+        int strlength; /* Length of string */<BR>
+        int tolen=0;<BR>
+        char * tmp;<BR>
+        <BR>
+        PyObject *ret; /* String object to return */<BR>
+<BR>
+        if (!PyArg_ParseTuple(args, &quot;s#&quot;, &amp;str, &amp;strlength))<BR>
+                return NULL;<BR>
+        <BR>
+        tmp = PQunescapeBytea(str,&amp;tolen);<BR>
+        ret = Py_BuildValue(&quot;s#&quot;, tmp, tolen);<BR>
+        PQfreemem(tmp);<BR>
+<BR>
+        if(!ret)<BR>
+                /* Pass on exception */<BR>
+                return NULL;<BR>
+<BR>
+        return ret;<BR>
+}<BR>
 <BR>
 /* pgobject methods */<BR>
 <BR>
@@ -3175,6 +3217,9 @@<BR>
 <BR>
 static struct PyMethodDef pg_methods[] = {<BR>
         {&quot;connect&quot;, (PyCFunction) pgconnect, 3, connect__doc__},<BR>
+        {&quot;pgbytea_escape&quot;,pgbytea_escape,METH_VARARGS,&quot;Escape bytea&quot;},<BR>
+        {&quot;pgbytea_unescape&quot;,pgbytea_unescape,METH_VARARGS,&quot;UnEscape bytea&quot;},<BR>
+        <BR>
 <BR>
 #ifdef DEFAULT_VARS<BR>
         {&quot;get_defhost&quot;, pggetdefhost, 1, getdefhost__doc__},<BR>
==CUT==<BR>
<BR>
Regards to all concerned,
<PRE><TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE><FONT COLOR="#f80000" SIZE="2">&nbsp; _____</FONT><FONT COLOR="#0000f8" SIZE="2">__&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ___&nbsp;&nbsp;&nbsp; </FONT><FONT COLOR="#f80000" SIZE="2">&nbsp;&nbsp; ___&nbsp; </FONT><FONT SIZE="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>
<FONT COLOR="#f80000" SIZE="2"> / ___/</FONT><FONT COLOR="#0000f8" SIZE="2"> /  ___ _____/ (_)__</FONT><FONT SIZE="2">&nbsp; </FONT><FONT COLOR="#f80000" SIZE="2"> / _ \</FONT><FONT COLOR="#0000f8" SIZE="2">__ _____ ___&nbsp; ___ </FONT>
<FONT COLOR="#f80000" SIZE="2">/ /__</FONT><FONT COLOR="#0000f8" SIZE="2">/ _ \/ _ `/ __/ / / -_)</FONT><FONT SIZE="2"> </FONT><FONT COLOR="#f80000" SIZE="2">/ // /</FONT><FONT COLOR="#0000f8" SIZE="2"> // (_-&lt;/ _ \/ _ \</FONT>
<FONT COLOR="#f80000" SIZE="2">\___/</FONT><FONT COLOR="#0000f8" SIZE="2">_//_/\_,_/_/ /_/_/\__/</FONT><FONT SIZE="2"> </FONT><FONT COLOR="#f80000" SIZE="2">/____/</FONT><FONT COLOR="#0000f8" SIZE="2">\_, /___/\___/_//_/</FONT>
<FONT SIZE="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT><FONT COLOR="#0000f8" SIZE="2"> /___/&nbsp;&nbsp;&nbsp;&nbsp;</FONT><FONT SIZE="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>
        <FONT COLOR="#000080">charlie at charlie dyson dot net</FONT></PRE>
</TD>
</TR>
</TABLE>
</PRE>
</BODY>
</HTML>