diff --git a/src/main/cpp/_nix_based/jssc.cpp b/src/main/cpp/_nix_based/jssc.cpp index 6887a0b6a..b10a5b1fb 100644 --- a/src/main/cpp/_nix_based/jssc.cpp +++ b/src/main/cpp/_nix_based/jssc.cpp @@ -22,9 +22,11 @@ * e-mail: scream3r.org@gmail.com * web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/ */ +#include #include #include #include +#include #include #include #include @@ -527,11 +529,21 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR */ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes (JNIEnv *env, jobject, jlong portHandle, jbyteArray buffer){ + jboolean ret = JNI_FALSE; jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); jint bufferSize = env->GetArrayLength(buffer); jint result = write(portHandle, jBuffer, (size_t)bufferSize); + if( result == -1 ){ + int err = errno; /*bakup errno*/ + jclass exClz = env->FindClass("java/io/IOException"); + assert(exClz != NULL); + env->ThrowNew(exClz, strerror(err)); + goto Finally; + } + ret = (result == bufferSize) ? JNI_TRUE : JNI_FALSE; +Finally: env->ReleaseByteArrayElements(buffer, jBuffer, 0); - return result == bufferSize ? JNI_TRUE : JNI_FALSE; + return ret; } /** diff --git a/src/main/java/jssc/SerialNativeInterface.java b/src/main/java/jssc/SerialNativeInterface.java index fced519c5..40022472e 100644 --- a/src/main/java/jssc/SerialNativeInterface.java +++ b/src/main/java/jssc/SerialNativeInterface.java @@ -277,7 +277,7 @@ public static String getLibraryVersion() { * * @return If the operation is successfully completed, the method returns true, otherwise false */ - public native boolean writeBytes(long handle, byte[] buffer); + public native boolean writeBytes(long handle, byte[] buffer) throws IOException; /** * Get bytes count in buffers of port diff --git a/src/main/java/jssc/SerialPort.java b/src/main/java/jssc/SerialPort.java index c2ded5307..713fa769c 100644 --- a/src/main/java/jssc/SerialPort.java +++ b/src/main/java/jssc/SerialPort.java @@ -24,6 +24,7 @@ */ package jssc; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; @@ -408,7 +409,11 @@ public boolean setDTR(boolean enabled) throws SerialPortException { */ public boolean writeBytes(byte[] buffer) throws SerialPortException { checkPortOpened("writeBytes()"); - return serialInterface.writeBytes(portHandle, buffer); + try { + return serialInterface.writeBytes(portHandle, buffer); + } catch(IOException ex) { + throw SerialPortException.wrapNativeException(ex, this, "writeBytes"); + } } /** diff --git a/src/main/java/jssc/SerialPortException.java b/src/main/java/jssc/SerialPortException.java index ba35e7684..b075aef40 100644 --- a/src/main/java/jssc/SerialPortException.java +++ b/src/main/java/jssc/SerialPortException.java @@ -67,6 +67,9 @@ public class SerialPortException extends Exception { */ final public static String TYPE_INCORRECT_SERIAL_PORT = "Incorrect serial port"; + /** Exception occurred in native code */ + final public static String TYPE_NATIVE_EXCEPTION = "Native exception occurred: %s"; + /** Serial port object **/ private SerialPort port; /** Method name **/ @@ -110,6 +113,10 @@ public SerialPortException(String portName, String methodName, String exceptionT this.exceptionType = exceptionType; } + public static SerialPortException wrapNativeException(Exception ex, SerialPort port, String methodName) { + return new SerialPortException(port, methodName, String.format(TYPE_NATIVE_EXCEPTION, ex.getLocalizedMessage())); + } + /** * Getting port name during operation with which the exception was called * Deprecated: Use getPort().getName() instead. diff --git a/src/test/java/jssc/SerialNativeInterfaceTest.java b/src/test/java/jssc/SerialNativeInterfaceTest.java index d0a2d6f2c..6890aab04 100644 --- a/src/test/java/jssc/SerialNativeInterfaceTest.java +++ b/src/test/java/jssc/SerialNativeInterfaceTest.java @@ -39,4 +39,12 @@ public void testPrintVersion() { } + @Test(expected = java.io.IOException.class) + public void reportsWriteErrorsAsIOException() throws Exception { + long fd = -1; /*bad file by intent*/ + byte[] buf = new byte[]{ 0x6A, 0x73, 0x73, 0x63, 0x0A }; + SerialNativeInterface testTarget = new SerialNativeInterface(); + testTarget.writeBytes(fd, buf); + } + }