Re: SWIG Java bindings
From: Daniel Rall <dlr_at_finemaltcoding.com>
Date: 2002-10-16 18:17:10 CEST
Morten Ludvigsen <morten_2ps_dk@yahoo.co.uk> writes:
> Is anyone actively working on SWIG-Java bindings?
Hi Morten. I've done a small amount of work on them. What I have is
--
Daniel Rall <dlr@finemaltcoding.com>
Index: ./svn_types.i
===================================================================
--- ./svn_types.i
+++ ./svn_types.i Wed Oct 16 09:01:38 2002
@@ -83,6 +83,9 @@
$1 = PyString_AS_STRING($input);
$2 = PyString_GET_SIZE($input);
}
+%typemap(java, in) (const char *PTR, apr_size_t LEN) {
+ /* FIXME: This is just a stub -- implement JNI code! */
+}
/* -----------------------------------------------------------------------
Define a generic arginit mapping for pools.
Index: ./svn_string.i
===================================================================
--- ./svn_string.i
+++ ./svn_string.i Wed Oct 16 09:01:03 2002
@@ -42,6 +42,10 @@
}
$result = t_output_helper($result, s);
}
+%typemap(java,argout,fragment="t_output_helper") RET_STRING {
+ /* FIXME: This is just a stub -- implement JNI code! */
+ return NULL;
+}
/* -----------------------------------------------------------------------
TYPE: svn_stringbuf_t
@@ -137,5 +141,8 @@
if ($1 == NULL)
return NULL;
}
+%typemap(java,in) const apr_array_header_t *STRINGLIST {
+ /* FIXME: This is just a stub -- implement JNI code! */
+}
/* ----------------------------------------------------------------------- */
Index: ./svn_fs.i
===================================================================
--- ./svn_fs.i
+++ ./svn_fs.i Fri Oct 11 19:46:41 2002
@@ -113,4 +113,8 @@
#ifdef SWIGPYTHON
#include "swigutil_py.h"
#endif
+
+#ifdef SWIGJAVA
+#include "swigutil_java.h"
+#endif
%}
Index: ./swigutil_java.c
===================================================================
--- ./swigutil_java.c
+++ ./swigutil_java.c Fri Oct 11 19:24:04 2002
@@ -0,0 +1,602 @@
+/*
+ * swigutil_java.c: utility functions for the SWIG Java bindings
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2002 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+
+#include <jni.h>
+
+#include <apr_pools.h>
+#include <apr_hash.h>
+
+#include "svn_string.h"
+#include "svn_delta.h"
+
+#include "swigutil_java.h"
+
+
+/* this baton is used for the editor, directory, and file batons. */
+typedef struct {
+ jobject editor; /* the editor handling the callbacks */
+ jobject baton; /* the dir/file baton (or NULL for edit baton) */
+ apr_pool_t *pool; /* pool to use for errors */
+} item_baton;
+
+typedef struct {
+ jobject handler; /* the window handler (a callable) */
+ apr_pool_t *pool; /* a pool for constructing errors */
+} handler_baton;
+
+
+static jobject make_pointer(const char *typename, void *ptr)
+{
+ /* ### cache the swig_type_info at some point? */
+ return SWIG_NewPointerObj(ptr, SWIG_TypeQuery(typename), 0);
+}
+
+/* for use by the "O&" format specifier */
+static jobject make_ob_pool(void *ptr)
+{
+ return make_pointer("apr_pool_t *", ptr);
+}
+
+/* for use by the "O&" format specifier */
+static jobject make_ob_window(void *ptr)
+{
+ return make_pointer("svn_txdelta_window_t *", ptr);
+}
+
+static jobject convert_hash(apr_hash_t *hash,
+ jobject (*converter_func)(void *value,
+ void *ctx),
+ void *ctx)
+{
+ apr_hash_index_t *hi;
+ jclass cls = JCALL1(FindClass, jenv, "java/util/HashMap");
+ jobject dict = JCALL3(NewObject, jenv, cls,
+ JCALL3(GetMethodID, jenv, cls, "<init>", "(I)V"),
+ (jint) apr_hash_count(hash));
+ jmethoID put = JCALL3(GetMethodID, jenv, cls, "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)"
+ "Ljava/lang/Object;"),
+
+ if (dict == NULL)
+ return NULL;
+
+ for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi))
+ {
+ const void *key;
+ void *val;
+ jobject value;
+
+ apr_hash_this(hi, &key, NULL, &val);
+ value = (*converter_func)(val, ctx);
+ JCALL3(CallObjectMethod, jenv, put,
+ JCALL2(NewString, jenv, key, strlen(key)), value);
+ JCALL1(DeleteLocalRef, jenv, value);
+ }
+
+ return dict;
+}
+
+static jobject convert_to_swigtype(void *value, void *ctx)
+{
+ /* ctx is a 'swig_type_info *' */
+ return SWIG_NewPointerObj(value, ctx, 0);
+}
+
+static jobject convert_svn_string_t(void *value, void *ctx)
+{
+ JNIEnv *jenv = (JNIEnv *) ctx;
+ const svn_string_t *s = value;
+
+ /* ### borrowing from value in the pool. or should we copy? note
+ ### that copying is "safest" */
+
+ return JCALL2(NewString, jenv, s->data, s->len);
+}
+
+
+jobject svn_swig_java_prophash_to_dict(JNIEnv *jenv, apr_hash_t *hash)
+{
+ return convert_hash(hash, convert_svn_string_t, jenv);
+}
+
+jobject svn_swig_java_convert_hash(JNIEnv *jenv, apr_hash_t *hash, swig_type_info *type)
+{
+ return convert_hash(hash, convert_to_swigtype, type);
+}
+
+jobject svn_swig_java_c_strings_to_list(JNIEnv *jenv, char **strings)
+{
+ jclass cls = JCALL1(FindClass, jenv, "java/util/ArrayList");
+ jobject list = JCALL2(NewObject, jenv, cls,
+ JCALL3(GetMethodID, jenv, cls, "<init>", "()V"));
+ jmethodID add = JCALL3(GetMethodID, jenv, cls, "add", "(Ljava/lang/Object;)Z");
+ char *s;
+ jobject obj;
+ while ((s = *strings++) != NULL)
+ {
+ obj = JCALL2(NewString, jenv, s, strlen(s));
+
+ if (obj == NULL)
+ goto error;
+
+ JCALL3(CallBooleanMethod, jenv, list, add, obj);
+
+ JCALL1(DeleteLocalRef, jenv, obj);
+ }
+
+ return list;
+
+ error:
+ JCALL1(DeleteLocalRef, jenv, list);
+ return NULL;
+}
+
+jobject svn_swig_java_array_to_list(JNIEnv *jenv, const apr_array_header_t *strings)
+{
+ jclass cls = JCALL1(FindClass, jenv, "java/util/ArrayList");
+ jobject list = JCALL3(NewObject, jenv, cls,
+ JCALL3(GetMethodID, jenv, cls, "<init>", "(I)V"),
+ strings->nelts);
+ int i;
+ jobject obj;
+
+ for (i = 0; i < strings->nelts; ++i)
+ {
+ const char *s;
+
+ s = APR_ARRAY_IDX(strings, i, const char *);
+ obj = JCALL2(NewString, jenv, s, strlen(s));
+ if (obj == NULL)
+ goto error;
+ PyList_SET_ITEM(list, i, obj);
+ JCALL1(DeleteLocaleRef, jenv, obj);
+ }
+
+ return list;
+
+ error:
+ JCALL1(DeleteLocaleRef, jenv, list);
+ return NULL;
+}
+
+const apr_array_header_t *svn_swig_java_strings_to_array(JNIEnv *jenv,
+ jobject source,
+ apr_pool_t *pool)
+{
+ int targlen;
+ apr_array_header_t *temp;
+
+ jclass cls = JCALL1(FindClass, jenv, "lang/util/List");
+ jmethodID size = JCALL3(GetMethodID, jenv, cls, "size", "()I");
+ jmethodID get = JCALL3(GetMethodID, jenv, cls, "get",
+ "(I)Ljava/lang/Object;");
+ if (!JCALL2(IsInstanceOf, jenv, source, cls))
+ {
+ /* FIXME: Resport by error (perhaps by throw an Exception)
+ PyErr_SetString(PyExc_TypeError, "not a sequence"); */
+ return NULL;
+ }
+ targlen = JCALL2(CallIntegerMethod, jenv, source, size);
+ temp = apr_array_make(pool, targlen, sizeof(const char *));
+ while (targlen--)
+ {
+ jobject o = JCALL3(CallObjectMethod, jenv, source, get, targlen);
+ if (o == NULL)
+ return NULL;
+ if (!PyString_Check(o))
+ {
+ JCALL1(DeleteLocalRef, jenv, o);
+ /* FIXME: Resport by error (perhaps by throw an Exception)
+ PyErr_SetString(PyExc_TypeError, "not a sequence"); */
+ return NULL;
+ }
+ APR_ARRAY_IDX(temp, targlen, const char *) = PyString_AS_STRING(o);
+ JCALL1(DeleteLocalRef, jenv, o);
+ }
+ return temp;
+}
+
+
+static svn_error_t * convert_java_error(JNIEnv *jenv, apr_pool_t *pool)
+{
+ /* ### need to fetch the Python error and map it to an svn_error_t */
+
+ return svn_error_create(APR_EGENERAL, 0, NULL, pool,
+ "the Python callback raised an exception");
+}
+
+static item_baton * make_baton(JNIEnv *jenv, apr_pool_t *pool,
+ jobject editor, jobject baton)
+{
+ item_baton *newb = apr_palloc(pool, sizeof(*newb));
+
+ /* one more reference to the editor. */
+ Py_INCREF(editor);
+
+ /* note: we take the caller's reference to 'baton' */
+
+ newb->editor = editor;
+ newb->baton = baton;
+ newb->pool = pool;
+
+ return newb;
+}
+
+static svn_error_t * close_baton(JNIEnv *jenv, void *baton, const char *method)
+{
+ item_baton *ib = baton;
+ jobject result;
+
+ /* If there is no baton object, then it is an edit_baton, and we should
+ not bother to pass an object. Note that we still shove a NULL onto
+ the stack, but the format specified just won't reference it. */
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)method,
+ ib->baton ? (char *)"O" : NULL,
+ ib->baton)) == NULL)
+ {
+ return convert_python_error(ib->pool);
+ }
+
+ /* there is no return value, so just toss this object (probably Py_None) */
+ Py_DECREF(result);
+
+ /* We're now done with the baton. Since there isn't really a free, all
+ we need to do is note that its objects are no longer referenced by
+ the baton. */
+ Py_DECREF(ib->editor);
+ Py_XDECREF(ib->baton);
+
+#ifdef SVN_DEBUG
+ ib->editor = ib->baton = NULL;
+#endif
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_set_target_revision(void *edit_baton,
+ svn_revnum_t target_revision)
+{
+ item_baton *ib = edit_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"set_target_revision",
+ (char *)"l", target_revision)) == NULL)
+ {
+ return convert_python_error(ib->pool);
+ }
+
+ /* there is no return value, so just toss this object (probably Py_None) */
+ Py_DECREF(result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_open_root(void *edit_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *dir_pool,
+ void **root_baton)
+{
+ item_baton *ib = edit_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"open_root",
+ (char *)"lO&", base_revision,
+ make_ob_pool, dir_pool)) == NULL)
+ {
+ return convert_python_error(dir_pool);
+ }
+
+ /* make_baton takes our 'result' reference */
+ *root_baton = make_baton(dir_pool, ib->editor, result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_delete_entry(const char *path,
+ svn_revnum_t revision,
+ void *parent_baton,
+ apr_pool_t *pool)
+{
+ item_baton *ib = parent_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"delete_entry",
+ (char *)"slOO&", path, revision, ib->baton,
+ make_ob_pool, pool)) == NULL)
+ {
+ return convert_python_error(pool);
+ }
+
+ /* there is no return value, so just toss this object (probably Py_None) */
+ Py_DECREF(result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_add_directory(const char *path,
+ void *parent_baton,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_revision,
+ apr_pool_t *dir_pool,
+ void **child_baton)
+{
+ item_baton *ib = parent_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"add_directory",
+ (char *)"sOslO&", path, ib->baton,
+ copyfrom_path, copyfrom_revision,
+ make_ob_pool, dir_pool)) == NULL)
+ {
+ return convert_python_error(dir_pool);
+ }
+
+ /* make_baton takes our 'result' reference */
+ *child_baton = make_baton(dir_pool, ib->editor, result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_open_directory(const char *path,
+ void *parent_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *dir_pool,
+ void **child_baton)
+{
+ item_baton *ib = parent_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"open_directory",
+ (char *)"sOlO&", path, ib->baton,
+ base_revision,
+ make_ob_pool, dir_pool)) == NULL)
+ {
+ return convert_python_error(dir_pool);
+ }
+
+ /* make_baton takes our 'result' reference */
+ *child_baton = make_baton(dir_pool, ib->editor, result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_change_dir_prop(void *dir_baton,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *pool)
+{
+ item_baton *ib = dir_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"change_dir_prop",
+ (char *)"Oss#O&", ib->baton, name,
+ value->data, value->len,
+ make_ob_pool, pool)) == NULL)
+ {
+ return convert_python_error(pool);
+ }
+
+ /* there is no return value, so just toss this object (probably Py_None) */
+ Py_DECREF(result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_close_directory(void *dir_baton)
+{
+ return close_baton(dir_baton, "close_directory");
+}
+
+static svn_error_t * thunk_add_file(const char *path,
+ void *parent_baton,
+ const char *copyfrom_path,
+ svn_revnum_t copyfrom_revision,
+ apr_pool_t *file_pool,
+ void **file_baton)
+{
+ item_baton *ib = parent_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"add_file",
+ (char *)"sOslO&", path, ib->baton,
+ copyfrom_path, copyfrom_revision,
+ make_ob_pool, file_pool)) == NULL)
+ {
+ return convert_python_error(file_pool);
+ }
+
+ /* make_baton takes our 'result' reference */
+ *file_baton = make_baton(file_pool, ib->editor, result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_open_file(const char *path,
+ void *parent_baton,
+ svn_revnum_t base_revision,
+ apr_pool_t *file_pool,
+ void **file_baton)
+{
+ item_baton *ib = parent_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"open_file",
+ (char *)"sOlO&", path, ib->baton,
+ base_revision,
+ make_ob_pool, file_pool)) == NULL)
+ {
+ return convert_python_error(file_pool);
+ }
+
+ /* make_baton takes our 'result' reference */
+ *file_baton = make_baton(file_pool, ib->editor, result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_window_handler(svn_txdelta_window_t *window,
+ void *baton)
+{
+ handler_baton *hb = baton;
+ jobject result;
+
+ if (window == NULL)
+ {
+ /* the last call; it closes the handler */
+
+ /* invoke the handler with None for the window */
+ /* ### python doesn't have 'const' on the format */
+ result = PyObject_CallFunction(hb->handler, (char *)"O", Py_None);
+
+ /* we no longer need to refer to the handler object */
+ Py_DECREF(hb->handler);
+ }
+ else
+ {
+ /* invoke the handler with the window */
+ /* ### python doesn't have 'const' on the format */
+ result = PyObject_CallFunction(hb->handler,
+ (char *)"O&", make_ob_window, window);
+ }
+
+ if (result == NULL)
+ return convert_python_error(hb->pool);
+
+ /* there is no return value, so just toss this object (probably Py_None) */
+ Py_DECREF(result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_apply_textdelta(
+ void *file_baton,
+ svn_txdelta_window_handler_t *handler,
+ void **h_baton)
+{
+ item_baton *ib = file_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"apply_textdelta",
+ (char *)"O", ib->baton)) == NULL)
+ {
+ return convert_python_error(ib->pool);
+ }
+
+ if (result == Py_None)
+ {
+ Py_DECREF(result);
+ *handler = NULL;
+ *h_baton = NULL;
+ }
+ else
+ {
+ handler_baton *hb = apr_palloc(ib->pool, sizeof(*hb));
+
+ /* return the thunk for invoking the handler. the baton takes our
+ 'result' reference. */
+ hb->handler = result;
+ hb->pool = ib->pool;
+
+ *handler = thunk_window_handler;
+ *h_baton = hb;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_change_file_prop(void *file_baton,
+ const char *name,
+ const svn_string_t *value,
+ apr_pool_t *pool)
+{
+ item_baton *ib = file_baton;
+ jobject result;
+
+ /* ### python doesn't have 'const' on the method name and format */
+ if ((result = PyObject_CallMethod(ib->editor, (char *)"change_file_prop",
+ (char *)"Oss#O&", ib->baton, name,
+ value->data, value->len,
+ make_ob_pool, pool)) == NULL)
+ {
+ return convert_python_error(pool);
+ }
+
+ /* there is no return value, so just toss this object (probably Py_None) */
+ Py_DECREF(result);
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t * thunk_close_file(void *file_baton)
+{
+ return close_baton(file_baton, "close_file");
+}
+
+static svn_error_t * thunk_close_edit(void *edit_baton)
+{
+ return close_baton(edit_baton, "close_edit");
+}
+
+static svn_error_t * thunk_abort_edit(void *edit_baton)
+{
+ return close_baton(edit_baton, "abort_edit");
+}
+
+static const svn_delta_editor_t thunk_editor = {
+ thunk_set_target_revision,
+ thunk_open_root,
+ thunk_delete_entry,
+ thunk_add_directory,
+ thunk_open_directory,
+ thunk_change_dir_prop,
+ thunk_close_directory,
+ thunk_add_file,
+ thunk_open_file,
+ thunk_apply_textdelta,
+ thunk_change_file_prop,
+ thunk_close_file,
+ thunk_close_edit,
+ thunk_abort_edit
+};
+
+void svn_swig_java_make_editor(JNIEnv *jenv,
+ const svn_delta_editor_t **editor,
+ void **edit_baton,
+ jobject java_editor,
+ apr_pool_t *pool)
+{
+ *editor = &thunk_editor;
+ *edit_baton = make_baton(pool, java_editor, NULL);
+}
+
+/* ----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../../tools/dev/svn-dev.el")
+ * end:
+ */
Index: ./svn_client.i
===================================================================
--- ./svn_client.i
+++ ./svn_client.i Wed Oct 16 09:15:22 2002
@@ -98,6 +98,12 @@
}
$result = t_output_helper($result, list);
}
+%typemap(java,argout) apr_hash_t **statushash {
+ /* FIXME: Use JNI equiv of Java type SWIGTYPE_p_svn_wc_status_t */
+ $result = t_output_helper(
+ $result,
+ svn_swig_java_convert_hash(*$1, SWIGTYPE_p_svn_wc_status_t));
+}
/* -----------------------------------------------------------------------
handle the "statushash" OUTPUT param for svn_client_status()
@@ -128,6 +134,10 @@
#ifdef SWIGPYTHON
#include "swigutil_py.h"
#endif
+
+#ifdef SWIGJAVA
+#include "swigutil_java.h"
+#endif
%}
%include svn_client.h
Index: ./swigutil_java.h
===================================================================
--- ./swigutil_java.h
+++ ./swigutil_java.h Fri Oct 11 19:24:04 2002
@@ -0,0 +1,103 @@
+/*
+ * swigutil_java.h : utility functions and stuff for the SWIG Java bindings
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2002 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+
+#ifndef SVN_SWIG_SWIGUTIL_JAVA_H
+#define SVN_SWIG_SWIGUTIL_JAVA_H
+
+#include <jni.h>
+
+#include <apr.h>
+#include <apr_pools.h>
+#include <apr_strings.h>
+#include <apr_hash.h>
+#include <apr_tables.h>
+
+#include "svn_types.h"
+#include "svn_string.h"
+#include "svn_delta.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* If this file is being included outside of a wrapper file, then need to
+ create stubs for some of the SWIG types. */
+
+/* if SWIGEXPORT is defined, then we're in a wrapper. otherwise, we need
+ the prototypes and type definitions. */
+#ifndef SWIGEXPORT
+#define SVN_NEED_SWIG_TYPES
+#endif
+
+#ifdef SVN_NEED_SWIG_TYPES
+
+typedef struct _unnamed swig_type_info;
+jobject *SWIG_NewPointerObj(JNIEnv *jenv, void *, swig_type_info *, int own);
+swig_type_info *SWIG_TypeQuery(JNIEnv *jenv, const char *name);
+
+#endif /* SVN_NEED_SWIG_TYPES */
+
+
+/* helper function to convert an apr_hash_t* (char* -> svnstring_t*) to
+ a Java Map */
+jobject svn_swig_java_prophash_to_dict(JNIEnv *jenv, apr_hash_t *hash);
+
+/* convert a hash of 'const char *' -> TYPE into a Java Map */
+jobject svn_swig_java_convert_hash(JNIEnv *jenv, apr_hash_t *hash,
+ swig_type_info *type);
+
+/* helper function to convert a 'char **' into a Java List of String
+ objects */
+jobject svn_swig_java_c_strings_to_list(JNIEnv *jenv, char **strings);
+
+/* helper function to convert an array of 'const char *' to a Java List of
+ String objects */
+jobject svn_swig_java_array_to_list(JNIEnv *jenv,
+ const apr_array_header_t *strings);
+
+/* helper function to convert a Java List of String objects into an
+ 'apr_array_header_t *' of 'const char *' objects. Note that the
+ objects must remain alive -- the values are not copied. This is
+ appropriate for incoming arguments which are defined to last the
+ duration of the function's execution. */
+const apr_array_header_t *svn_swig_java_strings_to_array(JNIEnv *jenv,
+ jobject source,
+ apr_pool_t *pool);
+
+/* make a editor that "thunks" from C callbacks up to Java */
+void svn_swig_java_make_editor(JNIEnv *jenv,
+ const svn_delta_editor_t **editor,
+ void **edit_baton,
+ jobject java_editor,
+ apr_pool_t *pool);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_SWIG_SWIGUTIL_JAVA_H */
+
+
+/* ----------------------------------------------------------------
+ * local variables:
+ * eval: (load-file "../../../tools/dev/svn-dev.el")
+ * end:
+ */
Index: ./util.i
===================================================================
--- ./util.i
+++ ./util.i Fri Oct 11 19:46:41 2002
@@ -189,4 +189,8 @@
#ifdef SWIGPYTHON
#include "swigutil_py.h"
#endif
+
+#ifdef SWIGJAVA
+#include "swigutil_java.h"
+#endif
%}
Index: ./svn_repos.i
===================================================================
--- ./svn_repos.i
+++ ./svn_repos.i Fri Oct 11 19:46:41 2002
@@ -62,4 +62,8 @@
#ifdef SWIGPYTHON
#include "swigutil_py.h"
#endif
+
+#ifdef SWIGJAVA
+#include "swigutil_java.h"
+#endif
%}
Index: ./svn_delta.i
===================================================================
--- ./svn_delta.i
+++ ./svn_delta.i Fri Oct 11 19:46:41 2002
@@ -82,4 +82,8 @@
#ifdef SWIGPYTHON
#include "swigutil_py.h"
#endif
+
+#ifdef SWIGJAVA
+#include "swigutil_java.h"
+#endif
%}
Index: ./apr.i
===================================================================
--- ./apr.i
+++ ./apr.i Wed Oct 16 08:15:40 2002
@@ -62,6 +62,12 @@
%typemap(python,argout,fragment="t_output_helper") apr_time_t * {
$result = t_output_helper($result, PyLong_FromLongLong(*$1));
}
+%typemap(java,argout) apr_time_t * {
+ jclass cls = JCALL1(FindClass, jenv, "java/lang/Long");
+ jmethodID ctor = JCALL3(GetMethodID, jenv, cls, "<init>", "(J)V");
+ jobject l = JCALL3(NewObject, jenv, cls, ctor, (jlong) *$1);
+ $result = t_output_helper($result, JCALL1(NewGlobalRef, jenv, l));
+}
/* -----------------------------------------------------------------------
create some INOUT typemaps for apr_size_t
@@ -73,6 +79,12 @@
temp = (apr_size_t) PyInt_AsLong($input);
$1 = &temp;
}
+%typemap(java,in) apr_size_t *INOUT (apr_size_t temp) {
+ jclass cls = JCALL1(FindClass, jenv, "java/lang/Long");
+ jmethodID mid = JCALL3(GetStaticMethodID, jenv, cls, "longValue", "()J");
+ temp = (apr_size_t) JCALL2(CallStaticLongMethod, jenv, mid, $input);
+ $1 = &temp;
+}
/* -----------------------------------------------------------------------
create an OUTPUT argument typemap for an apr_hash_t **
@@ -93,6 +105,12 @@
Py_DECREF($result);
$result = svn_swig_py_prophash_to_dict(*$1);
}
+%typemap(java,argout) apr_hash_t **PROPHASH {
+ /* toss prior result, get new result from the hash */
+ JCALL1(DeleteGlobalRef, jenv, $result);
+ $result = JCALL1(NewGlobalRef, jenv,
+ svn_swig_java_prophash_to_dict(jenv, *$1));
+}
/* -----------------------------------------------------------------------
apr_file_t ** is always an OUT param
@@ -105,6 +123,13 @@
$result = t_output_helper(
$result,
SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+%typemap(java,argout) apr_file_t ** {
+ /* HELP: Is there a JNI equivalent of SWIG_NewPointerObj, or is
+ this actually a cross-language typemap? */
+ $result = t_output_helper(
+ $result,
+ SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
}
/* ----------------------------------------------------------------------- */
Index: ./Makefile
===================================================================
--- ./Makefile
+++ ./Makefile Wed Oct 16 09:14:06 2002
@@ -0,0 +1,15 @@
+# TODO: Use -swiglig argument to avoid the need for SWIG-internal paths.
+SWIG_CMD=/usr/local/swig/bin/swig -c -java -noproxy -module 'svn_jni' -I'.' -I'../../include' -I'/home/dlr/src/apache.org/apr/include' -I'/usr/local/swig/lib/swig1.3' -I'/usr/local/swig/lib/swig1.3/java'
+
+build-java: swig-java
+
+swig-java:
+ for source in *.i; do \
+ target="`echo -n $$source | perl -pe 's/..$$/.jni.c/'`"; \
+ $(SWIG_CMD) -o $$target $$source; \
+ done; unset target source
+
+clean: swig-java-clean
+
+swig-java-clean:
+ rm -f *.jni.c *.java
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Oct 16 18:17:47 2002
|
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.