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 + -
显示快捷键?