diff options
Diffstat (limited to 'flow-native/src/flow_jni.c')
-rw-r--r-- | flow-native/src/flow_jni.c | 243 |
1 files changed, 112 insertions, 131 deletions
diff --git a/flow-native/src/flow_jni.c b/flow-native/src/flow_jni.c index 8ec2aed..75bffff 100644 --- a/flow-native/src/flow_jni.c +++ b/flow-native/src/flow_jni.c @@ -1,169 +1,150 @@ +#include <stdint.h> + #include "flow.h" -#include "com_github_jodersky_flow_internal_NativeSerial.h" +#include "ch_jodersky_flow_UnsafeSerial.h" +#include "ch_jodersky_flow_UnsafeSerial__.h" -static inline void throwException(JNIEnv* env, const char* const exception, const char * const message) { - (*env)->ThrowNew(env, (*env)->FindClass(env, exception), message); -} +// suppress unused parameter warnings +#define UNUSED_ARG(x) (void)(x) -static inline void check(JNIEnv* env, int id) { - switch (id) { - case E_IO: throwException(env, "java/io/IOException", ""); break; - case E_BUSY: throwException(env, "com/github/jodersky/flow/PortInUseException", ""); break; - case E_ACCESS_DENIED: throwException(env, "com/github/jodersky/flow/AccessDeniedException", ""); break; - case E_INVALID_SETTINGS: throwException(env, "com/github/jodersky/flow/InvalidSettingsException", ""); break; - case E_INTERRUPT: throwException(env, "com/github/jodersky/flow/PortInterruptedException", ""); break; - case E_NO_PORT: throwException(env, "com/github/jodersky/flow/NoSuchPortException", ""); break; - default: return; - } +static inline void throwException(JNIEnv* env, const char* const exception, const char * const message) +{ + (*env)->ThrowNew(env, (*env)->FindClass(env, exception), message); } - -/* - * Class: com_github_jodersky_flow_internal_NativeSerial - * Method: open - * Signature: (Ljava/lang/String;IIZI)J - */ -JNIEXPORT jlong JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_open - (JNIEnv *env, jclass clazz, jstring port_name, jint baud, jint char_size, jboolean two_stop_bits, jint parity) { - - const char *dev = (*env)->GetStringUTFChars(env, port_name, 0); - struct serial_config* config; - int r = serial_open(dev, baud, char_size, two_stop_bits, parity, &config); - (*env)->ReleaseStringUTFChars(env, port_name, dev); - - - if (r < 0) { - check(env, r); - return 0; - } - - long jpointer = (long) config; - return jpointer; +/** Check return code and throw exception in case it is non-zero. */ +static void check(JNIEnv* env, int ret) +{ + switch (ret) { + case -E_IO: throwException(env, "java/io/IOException", ""); break; + case -E_BUSY: throwException(env, "ch/jodersky/flow/PortInUseException", ""); break; + case -E_ACCESS_DENIED: throwException(env, "ch/jodersky/flow/AccessDeniedException", ""); break; + case -E_INVALID_SETTINGS: throwException(env, "ch/jodersky/flow/InvalidSettingsException", ""); break; + case -E_INTERRUPT: throwException(env, "ch/jodersky/flow/PortInterruptedException", ""); break; + case -E_NO_PORT: throwException(env, "ch/jodersky/flow/NoSuchPortException", ""); break; + default: return; + } +} +/** Get pointer to serial config associated to an UnsafeSerial instance. */ +static struct serial_config* get_config(JNIEnv* env, jobject unsafe_serial) +{ + jclass clazz = (*env)->FindClass(env, "ch/jodersky/flow/UnsafeSerial"); + jfieldID field = (*env)->GetFieldID(env, clazz, "serialAddr", "J"); + jlong addr = (*env)->GetLongField(env, unsafe_serial, field); + return (struct serial_config*) (intptr_t) addr; } /* - * Class: com_github_jodersky_flow_internal_NativeSerial - * Method: readDirect - * Signature: (JLjava/nio/ByteBuffer;)I + * Class: ch_jodersky_flow_UnsafeSerial__ + * Method: open + * Signature: (Ljava/lang/String;IIZI)J */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_readDirect - (JNIEnv *env, jclass clazz, jlong config, jobject buffer) { - - char* local_buffer = (char*) (*env)->GetDirectBufferAddress(env, buffer); - if (local_buffer == NULL) { - throwException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct"); - return -1; - } - jlong size = (*env)->GetDirectBufferCapacity(env, buffer); - - int r = serial_read((struct serial_config*) config, local_buffer, (size_t) size); - if (r < 0) { - check(env, r); - return -1; - } - return r; - +JNIEXPORT jlong JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_open +(JNIEnv *env, jobject instance, jstring port_name, jint baud, jint char_size, jboolean two_stop_bits, jint parity) +{ + UNUSED_ARG(instance); + + const char *dev = (*env)->GetStringUTFChars(env, port_name, 0); + struct serial_config* config; + int r = serial_open(dev, baud, char_size, two_stop_bits, parity, &config); + (*env)->ReleaseStringUTFChars(env, port_name, dev); + + if (r < 0) { + check(env, r); + return -E_IO; + } + + long jpointer = (long) config; + return (jlong) jpointer; } /* - * Class: com_github_jodersky_flow_internal_NativeSerial + * Class: ch_jodersky_flow_UnsafeSerial * Method: read - * Signature: (J[B)I + * Signature: (Ljava/nio/ByteBuffer;)I */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_read - (JNIEnv *env, jclass clazz, jlong config, jbyteArray buffer) { - - jsize size = (*env)->GetArrayLength(env, buffer); - char local_buffer[size]; - int r = serial_read((struct serial_config*) config, local_buffer, size); - if (r < 0) { - check(env, r); - return -1; - } - - (*env)->SetByteArrayRegion(env, buffer, 0, r, (signed char *) local_buffer); - return r; +JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_read +(JNIEnv *env, jobject instance, jobject buffer) +{ + char* local_buffer = (char*) (*env)->GetDirectBufferAddress(env, buffer); + if (local_buffer == NULL) { + throwException(env, "java/lang/IllegalArgumentException", "buffer is not direct"); + return -E_IO; + } + size_t size = (size_t) (*env)->GetDirectBufferCapacity(env, buffer); + struct serial_config* config = get_config(env, instance); + + int r = serial_read(config, local_buffer, size); + if (r < 0) { + check(env, r); + } + return r; } /* - * Class: com_github_jodersky_flow_internal_NativeSerial + * Class: ch_jodersky_flow_UnsafeSerial * Method: cancelRead - * Signature: (J)V + * Signature: ()V */ -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_cancelRead - (JNIEnv *env, jclass clazz, jlong config) { - - int r = serial_cancel_read((struct serial_config*) config); - if (r < 0) { - check(env, r); - } - +JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_cancelRead +(JNIEnv *env, jobject instance) +{ + int r = serial_cancel_read(get_config(env, instance)); + if (r < 0) { + check(env, r); + } } /* - * Class: com_github_jodersky_flow_internal_NativeSerial - * Method: writeDirect - * Signature: (JLjava/nio/ByteBuffer;I)I - */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_writeDirect - (JNIEnv *env, jclass clazz, jlong config, jobject buffer, jint size) { - - char* local_buffer = (char *) (*env)->GetDirectBufferAddress(env, buffer); - if (local_buffer == NULL) { - throwException(env, "java/lang/IllegalArgumentException", "ByteBuffer not direct"); - return -1; - } - - int r = serial_write((struct serial_config*) config, local_buffer, (size_t) size); - if (r < 0) { - check(env, r); - return -1; - } - return r; - -} - -/* - * Class: com_github_jodersky_flow_internal_NativeSerial + * Class: ch_jodersky_flow_UnsafeSerial * Method: write - * Signature: (J[BI)I + * Signature: (Ljava/nio/ByteBuffer;I)I */ -JNIEXPORT jint JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_write - (JNIEnv *env, jclass clazz, jlong config, jbyteArray buffer, jint size) { - - char* local_buffer = (char*) (*env)->GetByteArrayElements(env, buffer, NULL); - int r = serial_write((struct serial_config*) config, local_buffer, size); - (*env)->ReleaseByteArrayElements(env, buffer, (signed char*) local_buffer, JNI_ABORT); - if (r < 0) { - check(env, r); - return -1; - } - return r; - +JNIEXPORT jint JNICALL Java_ch_jodersky_flow_UnsafeSerial_write +(JNIEnv *env, jobject instance, jobject buffer, jint size) +{ + + char* local_buffer = (char *) (*env)->GetDirectBufferAddress(env, buffer); + if (local_buffer == NULL) { + throwException(env, "java/lang/IllegalArgumentException", "buffer is not direct"); + return -E_IO; + } + + int r = serial_write(get_config(env, instance), local_buffer, (size_t) size); + if (r < 0) { + check(env, r); + return -E_IO; + } + return r; } /* - * Class: com_github_jodersky_flow_internal_NativeSerial + * Class: ch_jodersky_flow_UnsafeSerial * Method: close - * Signature: (J)V + * Signature: ()V */ -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_close - (JNIEnv *env, jclass clazz, jlong config) { - int r = serial_close((struct serial_config*) config); - if (r < 0) { - check(env, r); - } +JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_close +(JNIEnv *env, jobject instance) +{ + int r = serial_close(get_config(env, instance)); + if (r < 0) { + check(env, r); + } } /* - * Class: com_github_jodersky_flow_internal_NativeSerial + * Class: ch_jodersky_flow_UnsafeSerial__ * Method: debug * Signature: (Z)V */ -JNIEXPORT void JNICALL Java_com_github_jodersky_flow_internal_NativeSerial_debug - (JNIEnv *env, jclass clazz, jboolean value) { - serial_debug((bool) value); -}
\ No newline at end of file +JNIEXPORT void JNICALL Java_ch_jodersky_flow_UnsafeSerial_00024_debug +(JNIEnv *env, jobject instance, jboolean value) +{ + UNUSED_ARG(env); + UNUSED_ARG(instance); + + serial_debug((bool) value); +} |