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.orgReceived 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.