Rev 1281: Implement tmp file callback. in http://people.samba.org/bzr/jelmer/bzr-svn/0.4

Jelmer Vernooij jelmer at samba.org
Sun Jun 22 22:14:32 BST 2008


At http://people.samba.org/bzr/jelmer/bzr-svn/0.4

------------------------------------------------------------
revno: 1281
revision-id: jelmer at samba.org-20080622211430-czw83hf2tvkfpaz8
parent: jelmer at samba.org-20080622203533-v5py10nydd42g0cj
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: 0.4
timestamp: Sun 2008-06-22 23:14:30 +0200
message:
  Implement tmp file callback.
modified:
  ra.c                           ra.pyx-20080313140933-qybkqaxe3m4mcll7-1
  util.c                         util.c-20080531154025-s8ef6ej9tytsnkkw-1
  util.h                         util.h-20080531154025-s8ef6ej9tytsnkkw-2
=== modified file 'ra.c'
--- a/ra.c	2008-06-22 20:35:33 +0000
+++ b/ra.c	2008-06-22 21:14:30 +0000
@@ -22,6 +22,7 @@
 #include <svn_ra.h>
 #include <svn_path.h>
 #include <apr_file_io.h>
+#include <apr_portable.h>
 
 #include <structmember.h>
 
@@ -464,6 +465,7 @@
 	AuthObject *auth;
 	bool busy;
 	PyObject *client_string_func;
+	PyObject *open_tmp_file_func;
 } RemoteAccessObject;
 
 static void ra_done_handler(void *_ra)
@@ -515,14 +517,55 @@
 }
 #endif
 
+/* Based on svn_swig_py_make_file() from Subversion */
 static svn_error_t *py_open_tmp_file(apr_file_t **fp, void *callback,
 									 apr_pool_t *pool)
 {
 	RemoteAccessObject *self = (RemoteAccessObject *)callback;
-
-	PyErr_SetString(PyExc_NotImplementedError, "open_tmp_file not wrapped yet");
+	PyObject *ret;
+	apr_status_t status;
+
+	if (self->open_tmp_file_func == Py_None) {
+		const char *path;
+
+		SVN_ERR (svn_io_temp_dir (&path, pool));
+		path = svn_path_join (path, "tempfile", pool);
+		SVN_ERR (svn_io_open_unique_file (fp, NULL, path, ".tmp", TRUE, pool));
+
+		return NULL;
+	}
+
+	ret = PyObject_CallFunction(self->open_tmp_file_func, "");
+
+	if (ret == NULL) 
+		return py_svn_error();
 	
-	return py_svn_error(); /* FIXME */
+	if (PyString_Check(ret)) {
+		char* fname = PyString_AsString(ret);
+		status = apr_file_open(fp, fname, APR_CREATE | APR_READ | APR_WRITE, APR_OS_DEFAULT, 
+								pool);
+		if (status) {
+			PyErr_SetAprStatus(status);
+			return NULL;
+		}
+	} else if (PyFile_Check(ret)) {
+		FILE *file;
+		apr_os_file_t osfile;
+
+		file = PyFile_AsFile(ret);
+#ifdef WIN32
+		osfile = (apr_os_file_t)_get_osfhandle(_fileno(file));
+#else
+		osfile = (apr_os_file_t)fileno(file);
+#endif
+		status = apr_os_file_put(fp, &osfile, O_CREAT | O_WRONLY, pool);
+		if (status) {
+			PyErr_SetAprStatus(status);
+			return NULL;
+		}
+	}
+
+	return NULL;
 }
 
 static void py_progress_func(apr_off_t progress, apr_off_t total, void *baton, apr_pool_t *pool)
@@ -539,19 +582,21 @@
 
 static PyObject *ra_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
-	char *kwnames[] = { "url", "progress_cb", "auth", "config", "client_string_func", NULL };
+	char *kwnames[] = { "url", "progress_cb", "auth", "config", "client_string_func", 
+		                "open_tmp_file_func", NULL };
 	char *url;
 	PyObject *progress_cb = Py_None;
 	AuthObject *auth = (AuthObject *)Py_None;
 	PyObject *config = Py_None;
-	PyObject *client_string_func = Py_None;
+	PyObject *client_string_func = Py_None, *open_tmp_file_func = Py_None;
 	RemoteAccessObject *ret;
 	apr_hash_t *config_hash;
 	svn_ra_callbacks2_t *callbacks2;
 	svn_auth_baton_t *auth_baton;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOOO", kwnames, &url, &progress_cb, 
-									 (PyObject **)&auth, &config, &client_string_func))
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOOOO", kwnames, &url, &progress_cb, 
+									 (PyObject **)&auth, &config, &client_string_func,
+									 &open_tmp_file_func))
 		return NULL;
 
 	ret = PyObject_New(RemoteAccessObject, &RemoteAccess_Type);
@@ -579,6 +624,7 @@
 	}
 
 	ret->client_string_func = client_string_func;
+	ret->open_tmp_file_func = open_tmp_file_func;
 	Py_INCREF(client_string_func);
 	callbacks2->progress_func = py_progress_func;
 	callbacks2->auth_baton = auth_baton;

=== modified file 'util.c'
--- a/util.c	2008-06-22 06:04:20 +0000
+++ b/util.c	2008-06-22 21:14:30 +0000
@@ -30,17 +30,23 @@
 #define BZR_SVN_APR_ERROR_OFFSET (APR_OS_START_USERERR + \
 								  (50 * SVN_ERR_CATEGORY_SIZE))
 
+void PyErr_SetAprStatus(apr_status_t status)
+{
+    char errmsg[1024];
+
+	PyErr_SetString(PyExc_Exception, 
+		apr_strerror(status, errmsg, sizeof(errmsg)));
+}
+
 
 apr_pool_t *Pool(apr_pool_t *parent)
 {
     apr_status_t status;
     apr_pool_t *ret;
-    char errmsg[1024];
     ret = NULL;
     status = apr_pool_create(&ret, parent);
     if (status != 0) {
-        PyErr_SetString(PyExc_Exception, 
-						apr_strerror(status, errmsg, sizeof(errmsg)));
+		PyErr_SetAprStatus(status);
 		return NULL;
 	}
     return ret;

=== modified file 'util.h'
--- a/util.h	2008-06-22 06:04:20 +0000
+++ b/util.h	2008-06-22 21:14:30 +0000
@@ -45,6 +45,7 @@
 PyObject *PyErr_NewSubversionException(svn_error_t *error);
 svn_error_t *py_cancel_func(void *cancel_baton);
 apr_hash_t *config_hash_from_object(PyObject *config, apr_pool_t *pool);
+void PyErr_SetAprStatus(apr_status_t status);
 
 #pragma GCC visibility pop
 




More information about the bazaar-commits mailing list