You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Brandon Ehle <az...@yahoo.com> on 2003/07/22 07:26:57 UTC

Correct way to add a svn_stream_from_pyio() wrapper?

|Here is my attempt at adding a svn_stream_from_pyio() wrapper so that 
you can pipe the output of svn_client_cat() directly to python.  It 
seems to work fine for both reads and writes, but I probably need to 
protect the .i file for Java and Perl.  Anybody know how to do this?


Index: swig/core.i
===================================================================
--- swig/core.i    (revision 6528)
+++ swig/core.i    (working copy)
@@ -217,6 +221,8 @@
 
 void apr_pool_destroy(apr_pool_t *p);
 
+svn_stream_t* svn_stream_from_pyio(PyObject *py_io, apr_pool_t *pool);
+
 /* 
----------------------------------------------------------------------- */
 
 %include svn_types.h
Index: swig/swigutil_py.c
===================================================================
--- swig/swigutil_py.c    (revision 6528)
+++ swig/swigutil_py.c    (working copy)
@@ -904,6 +904,98 @@
   return apr_file;
 }
 
+static svn_error_t *
+read_handler_pyio (void *baton, char *buffer, apr_size_t *len)
+{
+  PyObject *result;
+  PyObject *py_io = baton;
+  apr_size_t bytes;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  acquire_py_lock();
+  if ((result = PyObject_CallFunction(py_io, "read", "i", *len)) == NULL)
+    {
+      err = convert_python_error();
+    }
+  else if (PyString_Check(result))
+    {
+      bytes = PyString_GET_SIZE(result);
+      if (bytes>*len)
+        {
+          PyErr_SetString(PyExc_TypeError, "read_handler_pyio returned 
too many bytes");
+          err = convert_python_error();
+        }
+      else if (bytes<*len)
+        {
+          PyErr_SetString(PyExc_TypeError, "read_handler_pyio returned 
not enough bytes");
+          err = convert_python_error();
+          *len = bytes;
+        }
+
+      memcpy(buffer, PyString_AS_STRING(result), *len);
+    }
+  else
+    {
+      PyErr_SetString(PyExc_TypeError, "not a string");
+      err = convert_python_error();
+    }
+
+  Py_XDECREF(result);
+  release_py_lock();
+
+  return err;
+}
+
+
+static svn_error_t *
+write_handler_pyio (void *baton, const char *data, apr_size_t *len)
+{
+  PyObject *result;
+  PyObject *py_io = baton;
+  svn_error_t *err = SVN_NO_ERROR;
+
+  acquire_py_lock();
+  if ((result = PyObject_CallMethod(py_io, "write", "s#", data, *len)) 
== NULL)
+    {
+      err = convert_python_error();
+    }
+
+  Py_XDECREF(result);
+  release_py_lock();
+
+  return err;
+}
+
+static svn_error_t *
+close_handler_pyio (void *baton)
+{
+  PyObject *py_io = baton;
+
+  acquire_py_lock();
+  Py_XDECREF(py_io);
+  release_py_lock();
+
+  return SVN_NO_ERROR;
+}
+
+svn_stream_t *
+svn_stream_from_pyio (PyObject *py_io, apr_pool_t *pool)
+{
+  svn_stream_t *stream;
+
+  acquire_py_lock();
+  Py_INCREF(py_io);
+
+  stream = svn_stream_create (py_io, pool);
+  svn_stream_set_read (stream, read_handler_pyio);
+  svn_stream_set_write (stream, write_handler_pyio);
+  svn_stream_set_close (stream, close_handler_pyio);
+
+  release_py_lock();
+
+  return stream;
+}
+
 void svn_swig_py_notify_func(void *baton,
                              const char *path,
                              svn_wc_notify_action_t action,
Index: swig/swigutil_py.h
===================================================================
--- swig/swigutil_py.h    (revision 6528)
+++ swig/swigutil_py.h    (working copy)
@@ -97,6 +97,8 @@
 apr_file_t *svn_swig_py_make_file(PyObject *py_file,
                                   apr_pool_t *pool);
 
+svn_stream_t *svn_stream_from_pyio(PyObject *py_io, apr_pool_t *pool);
+
 /* a notify function that executes a Python function that is passed in
    via the baton argument */
 void svn_swig_py_notify_func(void *baton,
|


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org