swigutil_java.c
来自「linux subdivision ying gai ke yi le ba」· C语言 代码 · 共 1,257 行 · 第 1/3 页
C
1,257 行
callback_baton->jenv = jenv;
apr_pool_cleanup_register(pool, callback_baton,
callback_baton_cleanup_handler,
apr_pool_cleanup_null);
return callback_baton;
}
/* a notify function that executes a Java method on an object which is
passed in via the baton argument */
void svn_swig_java_notify_func(void *baton,
const char *path,
svn_wc_notify_action_t action,
svn_node_kind_t kind,
const char *mime_type,
svn_wc_notify_state_t content_state,
svn_wc_notify_state_t prop_state,
svn_revnum_t revision)
{
/* TODO: svn_swig_java_notify_func is not implemented yet */
}
/* a cancel function that executes a Java method on an object which is
passed in via the cancel_baton argument */
svn_error_t *svn_swig_java_cancel_func(void *cancel_baton)
{
/* TODO: svn_swig_java_cancel_func is not implemented yet */
return SVN_NO_ERROR;
}
/* thunked commit log fetcher */
svn_error_t *svn_swig_java_get_commit_log_func (const char **log_msg,
const char **tmp_file,
apr_array_header_t *commit_items,
void *baton,
apr_pool_t *pool)
{
return svn_error_create(APR_EGENERAL, NULL, "TODO: "
"svn_swig_java_get_commit_log_func is not "
"implemented yet");
}
/* log messages are returned in this */
svn_error_t *svn_swig_java_log_message_receiver(void *baton,
apr_hash_t *changed_paths,
svn_revnum_t revision,
const char *author,
const char *date, /* use svn_time_from_string() if need apr_time_t */
const char *message,
apr_pool_t *pool)
{
return svn_error_create
(APR_EGENERAL, NULL,
"TODO: svn_swig_java_get_commit_log_func is not implemented yet");
}
/* Prompt for username */
svn_error_t *svn_swig_java_client_prompt_func(const char **info,
const char *prompt,
svn_boolean_t hide,
void *baton,
apr_pool_t *pool)
{
callback_baton_t *callback_baton;
JNIEnv *jenv;
jobject callback;
jstring jprompt;
jstring jresult;
jboolean jhide;
const char *c_str;
svn_error_t *result;
callback_baton = (callback_baton_t *) baton;
jenv = callback_baton->jenv;
callback = callback_baton->callback;
/* Create a new local reference frame. Exit immediately
if functions fails. */
if (JCALL1(PushLocalFrame, jenv, 2) < 0)
{
return convert_exception(jenv, callback_baton->pool);
}
jprompt = JCALL1(NewStringUTF, jenv, prompt);
if (!jprompt)
{
goto error;
}
jhide = hide ? JNI_TRUE : JNI_FALSE;
jresult = JCALL4(CallObjectMethod, jenv, callback,
svn_swig_java_mid_clientprompt_prompt, jprompt, jhide);
if (!jresult)
{
goto error;
}
c_str = JCALL2(GetStringUTFChars, jenv, jresult, NULL);
if (!c_str)
{
goto error;
}
*info = apr_pstrdup(pool, c_str);
JCALL2(ReleaseStringUTFChars, jenv, jresult, c_str);
JCALL1(PopLocalFrame, jenv, NULL);
return SVN_NO_ERROR;
error:
result = convert_exception(jenv, callback_baton->pool);
JCALL1(PopLocalFrame, jenv, NULL);
return result;
}
/* This baton type is used for stream operations */
typedef struct {
jobject stream; /* Java stream object */
apr_pool_t *pool; /* pool to use for errors */
JNIEnv *jenv; /* Java native interface structure */
} stream_baton_t;
/* Create a stream baton. */
static stream_baton_t *make_stream_baton(JNIEnv *jenv,
jobject stream,
apr_pool_t *pool)
{
jobject globalref;
stream_baton_t *stream_baton;
/* The global reference is not necessary in all cases
e.g. for a call to svn_client_cat()
But we need it for svn_text_delta_t */
globalref = JCALL1(NewGlobalRef, jenv, stream);
if (globalref == NULL)
{
/* Exception occurred */
return 0;
}
stream_baton = apr_palloc(pool, sizeof(*stream_baton));
stream_baton->stream = globalref;
stream_baton->pool = pool;
stream_baton->jenv = jenv;
return stream_baton;
}
/* Pool cleanup handler. Removes global reference */
static apr_status_t stream_baton_cleanup_handler(void *baton)
{
stream_baton_t *stream_baton = (stream_baton_t *) baton;
JCALL1(DeleteGlobalRef, stream_baton->jenv, stream_baton->stream);
return APR_SUCCESS;
}
/* read/write/close functions for an OutputStream */
/* Read function for the OutputStream :-)
Since this is a write only stream we simply generate
an error. */
static svn_error_t *read_outputstream(void *baton,
char *buffer,
apr_size_t *len)
{
svn_error_t *svn_error = svn_error_create
(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL,
"Can't read from write only stream");
return svn_error;
}
/* Writes to the OutputStream */
static svn_error_t *write_outputstream(void *baton,
const char *buffer,
apr_size_t *len)
{
stream_baton_t *stream_baton;
JNIEnv *jenv;
jthrowable exc;
jbyteArray bytearray;
svn_error_t *result;
stream_baton = (stream_baton_t *) baton;
jenv = stream_baton->jenv;
bytearray = JCALL1(NewByteArray, jenv, (jsize) *len);
if (bytearray == NULL)
{
goto outofmemory_error;
}
JCALL4(SetByteArrayRegion, jenv, bytearray, (jsize) 0,
(jsize) *len, (jbyte *) buffer);
exc = JCALL0(ExceptionOccurred, jenv);
if (exc)
{
goto error;
}
JCALL3(CallVoidMethod, jenv, stream_baton->stream,
svn_swig_java_mid_outputstream_write, bytearray);
exc = JCALL0(ExceptionOccurred, jenv);
if (exc)
{
goto error;
}
JCALL1(DeleteLocalRef, jenv, bytearray);
return SVN_NO_ERROR;
outofmemory_error:
/* We now for sure that there is an exception pending */
exc = JCALL0(ExceptionOccurred, jenv);
error:
/* ### Better exception handling
At this point, we now that there is exception exc pending.
These are:
- OutOfMemoryError (NewByteArray)
- ArrayIndexOutOfBounds (SetByteArrayRegion)
- IOException (CallVoidMethod[write])
At least, the OutOfMemory error should get a special treatment... */
/* DEBUG JCALL0(ExceptionDescribe, jenv); */
JCALL0(ExceptionClear, jenv);
result = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL,
"Write error on stream");
JCALL1(DeleteLocalRef, jenv, exc);
return result;
}
/* Closes the OutputStream
Does nothing because we are not the owner of the stream.
May flush the stream in future. */
static svn_error_t *close_outputstream(void *baton)
{
return SVN_NO_ERROR;
}
/* read/write/close functions for an InputStream */
/* Reads from the InputStream */
static svn_error_t *read_inputstream(void *baton,
char *buffer,
apr_size_t *len)
{
stream_baton_t *stream_baton;
JNIEnv *jenv;
jthrowable exc;
jbyteArray bytearray;
jsize read_len;
svn_error_t *result;
stream_baton = (stream_baton_t *) baton;
jenv = stream_baton->jenv;
bytearray = JCALL1(NewByteArray, jenv, (jsize) *len);
if (bytearray == NULL)
{
goto outofmemory_error;
}
read_len = JCALL3(CallIntMethod, jenv, stream_baton->stream,
svn_swig_java_mid_inputstream_read, bytearray);
exc = JCALL0(ExceptionOccurred, jenv);
if (exc)
{
goto error;
}
if (read_len > 0)
{
JCALL4(GetByteArrayRegion, jenv, bytearray, (jsize) 0, (jsize) read_len,
(jbyte *) buffer);
exc = JCALL0(ExceptionOccurred, jenv);
if (exc)
{
goto error;
}
}
else
{
read_len = 0; /* -1 is EOF, svn_stream_t wants 0 */
}
JCALL1(DeleteLocalRef, jenv, bytearray);
*len = read_len;
return SVN_NO_ERROR;
outofmemory_error:
/* We now for sure that there is an exception pending */
exc = JCALL0(ExceptionOccurred, jenv);
error:
/* ### Better exception handling
At this point, we now that there is exception exc pending.
These are:
- OutOfMemoryError (NewByteArray)
- ArrayIndexOutOfBounds (SetByteArrayRegion)
- IOException (CallIntMethod[read])
At least, the OutOfMemory error should get a special treatment... */
/* DEBUG JCALL0(ExceptionDescribe, jenv); */
JCALL0(ExceptionClear, jenv);
result = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL,
"Write error on stream");
JCALL1(DeleteLocalRef, jenv, exc);
return result;
}
/* Write function for the InputStream :-)
Since this is a read only stream we simply generate
an error. */
static svn_error_t *write_inputstream(void *baton,
const char *buffer,
apr_size_t *len)
{
svn_error_t *svn_error = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF,
NULL,
"Can't write on read only stream");
return svn_error;
}
/* Closes the InputStream
Does nothing because we are not the owner of the stream. */
static svn_error_t *close_inputstream(void *baton)
{
return SVN_NO_ERROR;
}
/* Create a svn_stream_t from a java.io.OutputStream object.
Registers a pool cleanup handler for deallocating JVM
resources. */
svn_stream_t *svn_swig_java_outputstream_to_stream(JNIEnv *jenv,
jobject outputstream, apr_pool_t *pool)
{
stream_baton_t *baton;
svn_stream_t *stream;
baton = make_stream_baton(jenv, outputstream, pool);
if (baton == NULL)
{
return NULL;
}
apr_pool_cleanup_register(pool, baton, stream_baton_cleanup_handler,
apr_pool_cleanup_null);
stream = svn_stream_create(baton, pool);
if (stream == NULL)
{
return NULL;
}
svn_stream_set_read(stream, read_outputstream);
svn_stream_set_write(stream, write_outputstream);
svn_stream_set_close(stream, close_outputstream);
return stream;
}
/* Create a svn_stream_t from a java.io.InputStream object.
Registers a pool cleanup handler for deallocating JVM
resources. */
svn_stream_t *svn_swig_java_inputstream_to_stream(JNIEnv *jenv,
jobject inputstream, apr_pool_t *pool)
{
stream_baton_t *baton;
svn_stream_t *stream;
baton = make_stream_baton(jenv, inputstream, pool);
if (baton == NULL)
{
return NULL;
}
apr_pool_cleanup_register(pool, baton, stream_baton_cleanup_handler,
apr_pool_cleanup_null);
stream = svn_stream_create(baton, pool);
if (stream == NULL)
{
return NULL;
}
svn_stream_set_read(stream, read_inputstream);
svn_stream_set_write(stream, write_inputstream);
svn_stream_set_close(stream, close_inputstream);
return stream;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *jenv;
if ((*jvm)->GetEnv(jvm, (void **) &jenv, JNI_VERSION_1_2))
{
return JNI_ERR;
}
#define SVN_SWIG_JAVA_INIT_CACHE
#include "swigutil_java_cache.h"
return JNI_VERSION_1_2;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)
{
JNIEnv *jenv;
if ((*jvm)->GetEnv(jvm, (void **) &jenv, JNI_VERSION_1_2))
{
return;
}
#define SVN_SWIG_JAVA_TERM_CACHE
#include "swigutil_java_cache.h"
}
/* HACK: Assure that libtool includes the symbol for any symbols we
may need auto-loaded (e.g. apr_initialize()). Preferably this
function would be static, but uncertain whether a compiler would
optimize it out entirely (since it isn't called). */
void svn_swig_java__libtool_hack()
{
apr_initialize();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?