diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | bindings/java/Context.cpp | 106 | ||||
-rwxr-xr-x[-rw-r--r--] | bindings/java/Socket.cpp | 197 | ||||
-rwxr-xr-x[-rw-r--r--] | bindings/java/org/zmq/Context.java | 17 | ||||
-rwxr-xr-x[-rw-r--r--] | bindings/java/org/zmq/Socket.java | 59 |
5 files changed, 267 insertions, 113 deletions
@@ -13,6 +13,7 @@ Erich Heine Erik Rigtorp Frank Denis George Neill +Gonzalo Diethelm Joe Thornber Jon Dyte Kamil Shakirov diff --git a/bindings/java/Context.cpp b/bindings/java/Context.cpp index f3f74ff..d2b5e42 100644..100755 --- a/bindings/java/Context.cpp +++ b/bindings/java/Context.cpp @@ -17,8 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdlib.h> -#include <string.h> #include <assert.h> #include <errno.h> @@ -26,9 +24,51 @@ #include "org_zmq_Context.h" +/** Handle to Java's Context::contextHandle. */ static jfieldID ctx_handle_fid = NULL; -static void raise_exception (JNIEnv *env, int err) +/** + * Make sure we have a valid pointer to Java's Context::contextHandle. + */ +static void ensure_context (JNIEnv *env, + jobject obj) +{ + if (ctx_handle_fid == NULL) { + jclass cls = env->GetObjectClass (obj); + assert (cls); + ctx_handle_fid = env->GetFieldID (cls, "contextHandle", "J"); + assert (ctx_handle_fid); + env->DeleteLocalRef (cls); + } +} + +/** + * Get the value of Java's Context::contextHandle. + */ +static void *get_context (JNIEnv *env, + jobject obj) +{ + ensure_context (env, obj); + void *s = (void*) env->GetLongField (obj, ctx_handle_fid); + return s; +} + +/** + * Set the value of Java's Context::contextHandle. + */ +static void put_context (JNIEnv *env, + jobject obj, + void *s) +{ + ensure_context (env, obj); + env->SetLongField (obj, ctx_handle_fid, (jlong) s); +} + +/** + * Raise an exception that includes 0MQ's error message. + */ +static void raise_exception (JNIEnv *env, + int err) { // Get exception class. jclass exception_class = env->FindClass ("java/lang/Exception"); @@ -39,52 +79,42 @@ static void raise_exception (JNIEnv *env, int err) // Raise the exception. int rc = env->ThrowNew (exception_class, err_msg); - assert (rc == 0); - - // Free the local ref. env->DeleteLocalRef (exception_class); + + assert (rc == 0); } -JNIEXPORT void JNICALL Java_org_zmq_Context_construct (JNIEnv *env, jobject obj, - jint app_threads, jint io_threads, jint flags) +/** + * Called to construct a Java Context object. + */ +JNIEXPORT void JNICALL Java_org_zmq_Context_construct (JNIEnv *env, + jobject obj, + jint app_threads, + jint io_threads, + jint flags) { - if (ctx_handle_fid == NULL) { - jclass cls = env->GetObjectClass (obj); - assert (cls); - ctx_handle_fid = env->GetFieldID (cls, "contextHandle", "J"); - assert (ctx_handle_fid); - env->DeleteLocalRef (cls); - } + void *c = get_context (env, obj); + assert (! c); + + c = zmq_init (app_threads, io_threads, flags); + put_context(env, obj, c); - void *ctx = zmq_init (app_threads, io_threads, flags); - if (ctx == NULL) { + if (c == NULL) { raise_exception (env, errno); return; } - - env->SetLongField (obj, ctx_handle_fid, (jlong) ctx); } -JNIEXPORT void JNICALL Java_org_zmq_Context_finalize (JNIEnv *env, jobject obj) +/** + * Called to destroy a Java Context object. + */ +JNIEXPORT void JNICALL Java_org_zmq_Context_finalize (JNIEnv *env, + jobject obj) { - void *ctx = (void*) env->GetLongField (obj, ctx_handle_fid); - assert (ctx); + void *c = get_context (env, obj); + assert (c); - int rc = zmq_term (ctx); + int rc = zmq_term (c); + put_context (env, obj, NULL); assert (rc == 0); } - -JNIEXPORT jlong JNICALL Java_org_zmq_Context_createSocket (JNIEnv *env, - jobject obj, jint type) -{ - void *ctx = (void*) env->GetLongField (obj, ctx_handle_fid); - assert (ctx); - - void *s = zmq_socket (ctx, type); - if (s == NULL) { - raise_exception (env, errno); - return -1; - } - - return (jlong) s; -} diff --git a/bindings/java/Socket.cpp b/bindings/java/Socket.cpp index eaf1b22..adea3fa 100644..100755 --- a/bindings/java/Socket.cpp +++ b/bindings/java/Socket.cpp @@ -17,7 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdlib.h> #include <string.h> #include <assert.h> #include <errno.h> @@ -27,9 +26,79 @@ #include "org_zmq_Socket.h" +/** Handle to Java's Socket::socketHandle. */ static jfieldID socket_handle_fid = NULL; -static jmethodID create_socket_mid = NULL; +/** + * Make sure we have a valid pointer to Java's Socket::socketHandle. + */ +static void ensure_socket (JNIEnv *env, + jobject obj) +{ + if (socket_handle_fid == NULL) { + jclass cls = env->GetObjectClass (obj); + assert (cls); + socket_handle_fid = env->GetFieldID (cls, "socketHandle", "J"); + assert (socket_handle_fid); + env->DeleteLocalRef (cls); + } +} + +/** + * Get the value of Java's Socket::socketHandle. + */ +static void *get_socket (JNIEnv *env, + jobject obj) +{ + ensure_socket (env, obj); + void *s = (void*) env->GetLongField (obj, socket_handle_fid); + return s; +} + +/** + * Set the value of Java's Socket::socketHandle. + */ +static void put_socket (JNIEnv *env, + jobject obj, + void *s) +{ + ensure_socket (env, obj); + env->SetLongField (obj, socket_handle_fid, (jlong) s); +} + +/** + * Get the value of contextHandle for the Java Context associated with + * this Java Socket object. + */ +static void *fetch_context (JNIEnv *env, + jobject context) +{ + static jmethodID get_context_handle_mid = NULL; + + if (get_context_handle_mid == NULL) { + jclass cls = env->GetObjectClass (context); + assert (cls); + + get_context_handle_mid = env->GetMethodID (cls, + "getContextHandle", + "()J"); + env->DeleteLocalRef (cls); + assert (get_context_handle_mid); + } + + void *zmq_ctx = (void*) env->CallLongMethod (context, + get_context_handle_mid); + if (env->ExceptionCheck ()) { + zmq_ctx = NULL; + } + + assert (zmq_ctx); + return zmq_ctx; +} + +/** + * Raise an exception that includes 0MQ's error message. + */ static void raise_exception (JNIEnv *env, int err) { // Get exception class. @@ -41,46 +110,49 @@ static void raise_exception (JNIEnv *env, int err) // Raise the exception. int rc = env->ThrowNew (exception_class, err_msg); - assert (rc == 0); - - // Free the local ref. env->DeleteLocalRef (exception_class); + + assert (rc == 0); } -JNIEXPORT void JNICALL Java_org_zmq_Socket_construct (JNIEnv *env, jobject obj, - jobject context, jint type) +/** + * Called to construct a Java Socket object. + */ +JNIEXPORT void JNICALL Java_org_zmq_Socket_construct (JNIEnv *env, + jobject obj, + jobject context, + jint type) { - if (socket_handle_fid == NULL) { - jclass cls = env->GetObjectClass (obj); - assert (cls); - socket_handle_fid = env->GetFieldID (cls, "socketHandle", "J"); - assert (socket_handle_fid); - env->DeleteLocalRef (cls); - } + void *s = get_socket (env, obj); + assert (! s); - if (create_socket_mid == NULL) { - jclass cls = env->FindClass ("org/zmq/Context"); - assert (cls); - create_socket_mid = env->GetMethodID (cls, "createSocket", "(I)J"); - assert (create_socket_mid); - env->DeleteLocalRef (cls); - } - - void *s = (void*) env->CallLongMethod (context, create_socket_mid, type); - if (env->ExceptionCheck ()) - return; + void *zmq_ctx = fetch_context (env, context); + s = zmq_socket (zmq_ctx, type); + put_socket(env, obj, s); - env->SetLongField (obj, socket_handle_fid, (jlong) s); + if (s == NULL) { + raise_exception (env, errno); + return; + } } -JNIEXPORT void JNICALL Java_org_zmq_Socket_finalize (JNIEnv *env, jobject obj) +/** + * Called to destroy a Java Socket object. + */ +JNIEXPORT void JNICALL Java_org_zmq_Socket_finalize (JNIEnv *env, + jobject obj) { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); + int rc = zmq_close (s); + put_socket (env, obj, NULL); assert (rc == 0); } +/** + * Called by Java's Socket::setsockopt(int option, long optval). + */ JNIEXPORT void JNICALL Java_org_zmq_Socket_setsockopt__IJ (JNIEnv *env, jobject obj, jint option, jlong optval) { @@ -93,7 +165,7 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_setsockopt__IJ (JNIEnv *env, case ZMQ_RECOVERY_IVL: case ZMQ_MCAST_LOOP: { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); int64_t value = optval; @@ -108,8 +180,14 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_setsockopt__IJ (JNIEnv *env, } } +/** + * Called by Java's Socket::setsockopt(int option, String optval). + */ JNIEXPORT void JNICALL Java_org_zmq_Socket_setsockopt__ILjava_lang_String_2 ( - JNIEnv *env, jobject obj, jint option, jstring optval) + JNIEnv *env, + jobject obj, + jint option, + jstring optval) { switch (option) { case ZMQ_IDENTITY: @@ -121,8 +199,8 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_setsockopt__ILjava_lang_String_2 ( return; } - void *s = (void*) env->GetLongField (obj, socket_handle_fid); - assert (s); + void *s = get_socket (env, obj); + assert (s); const char *value = env->GetStringUTFChars (optval, NULL); assert (value); @@ -138,10 +216,14 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_setsockopt__ILjava_lang_String_2 ( } } -JNIEXPORT void JNICALL Java_org_zmq_Socket_bind (JNIEnv *env, jobject obj, - jstring addr) +/** + * Called by Java's Socket::bind(String addr). + */ +JNIEXPORT void JNICALL Java_org_zmq_Socket_bind (JNIEnv *env, + jobject obj, + jstring addr) { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); if (addr == NULL) { @@ -162,10 +244,14 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_bind (JNIEnv *env, jobject obj, raise_exception (env, errno); } -JNIEXPORT void JNICALL Java_org_zmq_Socket_connect (JNIEnv *env, jobject obj, - jstring addr) +/** + * Called by Java's Socket::connect(String addr). + */ +JNIEXPORT void JNICALL Java_org_zmq_Socket_connect (JNIEnv *env, + jobject obj, + jstring addr) { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); if (addr == NULL) { @@ -186,10 +272,15 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_connect (JNIEnv *env, jobject obj, raise_exception (env, errno); } -JNIEXPORT jboolean JNICALL Java_org_zmq_Socket_send (JNIEnv *env, jobject obj, - jbyteArray msg, jlong flags) +/** + * Called by Java's Socket::send(byte [] msg, long flags). + */ +JNIEXPORT jboolean JNICALL Java_org_zmq_Socket_send (JNIEnv *env, + jobject obj, + jbyteArray msg, + jlong flags) { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); jsize size = env->GetArrayLength (msg); @@ -222,9 +313,13 @@ JNIEXPORT jboolean JNICALL Java_org_zmq_Socket_send (JNIEnv *env, jobject obj, return JNI_TRUE; } -JNIEXPORT void JNICALL Java_org_zmq_Socket_flush (JNIEnv *env, jobject obj) +/** + * Called by Java's Socket::flush(). + */ +JNIEXPORT void JNICALL Java_org_zmq_Socket_flush (JNIEnv *env, + jobject obj) { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); int rc = zmq_flush (s); @@ -235,10 +330,14 @@ JNIEXPORT void JNICALL Java_org_zmq_Socket_flush (JNIEnv *env, jobject obj) } } -JNIEXPORT jbyteArray JNICALL Java_org_zmq_Socket_recv (JNIEnv *env, jobject obj, - jlong flags) +/** + * Called by Java's Socket::recv(long flags). + */ +JNIEXPORT jbyteArray JNICALL Java_org_zmq_Socket_recv (JNIEnv *env, + jobject obj, + jlong flags) { - void *s = (void*) env->GetLongField (obj, socket_handle_fid); + void *s = get_socket (env, obj); assert (s); zmq_msg_t message; @@ -258,8 +357,10 @@ JNIEXPORT jbyteArray JNICALL Java_org_zmq_Socket_recv (JNIEnv *env, jobject obj, jbyteArray data = env->NewByteArray (zmq_msg_size (&message)); assert (data); - env->SetByteArrayRegion (data, 0, zmq_msg_size (&message), - (jbyte*) zmq_msg_data (&message)); + env->SetByteArrayRegion (data, + 0, + zmq_msg_size (&message), + (jbyte*) zmq_msg_data (&message)); return data; } diff --git a/bindings/java/org/zmq/Context.java b/bindings/java/org/zmq/Context.java index 3c00ba8..219b26c 100644..100755 --- a/bindings/java/org/zmq/Context.java +++ b/bindings/java/org/zmq/Context.java @@ -36,17 +36,22 @@ public class Context { construct (appThreads, ioThreads, flags); } - /** - * Internal function. Do not use directly! - */ - public native long createSocket (int type); - /** Initialize the JNI interface */ protected native void construct (int appThreads, int ioThreads, int flags); - /** Free resources used by JNI driver. */ + /** Free all resources used by JNI interface. */ protected native void finalize (); + /** + * Get the underlying context handle. + * + * @return the internal 0MQ context handle. + */ + private long getContextHandle () { + return contextHandle; + } + + /** Opaque data used by JNI driver. */ private long contextHandle; } diff --git a/bindings/java/org/zmq/Socket.java b/bindings/java/org/zmq/Socket.java index 1b427c3..1815b53 100644..100755 --- a/bindings/java/org/zmq/Socket.java +++ b/bindings/java/org/zmq/Socket.java @@ -1,4 +1,4 @@ - /* +/* Copyright (c) 2007-2010 iMatix Corporation This file is part of 0MQ. @@ -19,9 +19,7 @@ package org.zmq; -public class Socket -{ - +public class Socket { static { System.loadLibrary("jzmq"); } @@ -52,44 +50,53 @@ public class Socket public static final int SNDBUF = 11; public static final int RCVBUF = 12; + /** * Class constructor. * - * @param context - * @param type + * @param context a 0MQ context previously created. + * @param type the socket type. */ public Socket (Context context, int type) { construct (context, type); } /** - * Set the socket option value. + * Set the socket option value, given as a long. + * + * @param option ID of the option to set. + * @param optval value (as a long) to set the option to. + */ + public native void setsockopt (int option, long optval); + + /** + * Set the socket option value, given as a String. * - * @param option ID of the option to set - * @param optval value to set the option to + * @param option ID of the option to set. + * @param optval value (as a String) to set the option to. */ - public native void setsockopt (int option, long optval); - public native void setsockopt (int option, String optval); + public native void setsockopt (int option, String optval); /** * Bind to network interface. Start listening for new connections. * - * @param addr + * @param addr the endpoint to bind to. */ public native void bind (String addr); /** * Connect to remote application. * - * @param addr + * @param addr the endpoint to connect to. */ public native void connect (String addr); /** - * Send the message. + * Send a message. * - * @param msg - * @param flags + * @param msg the message to send, as an array of bytes. + * @param flags the flags to apply to the send operation. + * @return true if send was successful, false otherwise. */ public native boolean send (byte [] msg, long flags); @@ -99,19 +106,29 @@ public class Socket public native void flush (); /** - * Receive message. + * Receive a message. * - * @param flags - * @return + * @param flags the flags to apply to the receive operation. + * @return the message received, as an array of bytes; null on error. */ public native byte [] recv (long flags); - /** Initialize JNI driver */ + /** Initialize the JNI interface */ protected native void construct (Context context, int type); - /** Free all resources used by JNI driver. */ + /** Free all resources used by JNI interface. */ protected native void finalize (); + /** + * Get the underlying socket handle. + * + * @return the internal 0MQ socket handle. + */ + private long getSocketHandle () { + return socketHandle; + } + + /** Opaque data used by JNI driver. */ private long socketHandle; |