Skip to content

Commit

Permalink
Make 'write()' return number of bytes written
Browse files Browse the repository at this point in the history
Some thoughts about java-native#129

What this commit does:

- Make native impls return numberOfBytesWritten.
- Throw SerialPortException in case write fails in some way.
- Expose new 'write()' method to java which returns
  numberOfBytesWritten and uses exceptions for error handling.
- Keep old 'writeBytes()' method and translate to the old behavior.

What this commit does NOT:

THIS CODE IS NOT TESTED! It even was not launched at all. Nevertheless
it did compile fine for x86_64-linux-gnu (debian) and mingw
(cross-compile). So we need to do:

- Testing!
- Review if the change in the API (adding a 'write()' method) is the
  thing we should do or if we should do it differently somehow.

(wip @ 36ee5d8)
  • Loading branch information
hiddenalpha committed Oct 3, 2022
1 parent 6886b44 commit 7ed987d
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/main/cpp/_nix_based/jssc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
Expand Down Expand Up @@ -525,13 +526,16 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR
/*
* Writing data to the port
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_write
(JNIEnv *env, jobject, jlong portHandle, jbyteArray buffer){
jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE);
jint bufferSize = env->GetArrayLength(buffer);
jint result = write(portHandle, jBuffer, (size_t)bufferSize);
env->ReleaseByteArrayElements(buffer, jBuffer, 0);
return result == bufferSize ? JNI_TRUE : JNI_FALSE;
if( result < 0 ){ /* aka error */
return env->ThrowNew(env->FindClass("jssc/SerialPortException"), strerror(errno));
}
return result;
}

/**
Expand Down
11 changes: 7 additions & 4 deletions src/main/cpp/windows/jssc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,28 +231,31 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR
* portHandle - port handle
* buffer - byte array for sending
*/
JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes
JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_write
(JNIEnv *env, jobject, jlong portHandle, jbyteArray buffer){
HANDLE hComm = (HANDLE)portHandle;
DWORD lpNumberOfBytesTransferred;
DWORD lpNumberOfBytesWritten;
OVERLAPPED *overlapped = new OVERLAPPED();
jboolean returnValue = JNI_FALSE;
jint returnValue = -1;
jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE);
overlapped->hEvent = CreateEventA(NULL, true, false, NULL);
if(WriteFile(hComm, jBuffer, (DWORD)env->GetArrayLength(buffer), &lpNumberOfBytesWritten, overlapped)){
returnValue = JNI_TRUE;
returnValue = lpNumberOfBytesWritten;
}
else if(GetLastError() == ERROR_IO_PENDING){
if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){
if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){
returnValue = JNI_TRUE;
returnValue = lpNumberOfBytesTransferred;
}
}
}
env->ReleaseByteArrayElements(buffer, jBuffer, 0);
CloseHandle(overlapped->hEvent);
delete overlapped;
if( returnValue < 0 ){
return env->ThrowNew(env->FindClass("jssc/SerialPortException"), "WriteFile() failed");
}
return returnValue;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/jssc/SerialNativeInterface.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 int write(long handle, byte[] buffer) throws SerialPortException;

/**
* Get bytes count in buffers of port
Expand Down
24 changes: 23 additions & 1 deletion src/main/java/jssc/SerialPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,28 @@ public boolean setDTR(boolean enabled) throws SerialPortException {
*/
public boolean writeBytes(byte[] buffer) throws SerialPortException {
checkPortOpened("writeBytes()");
return serialInterface.writeBytes(portHandle, buffer);
// Delegate to new method and translate result to what original method
// did return.
try{
int result = write(buffer);
return result == buffer.length;
}catch (SerialPortException ex) {
return false;
}
}

/**
* Write byte array to port
*
* @param buffer <code>byte[]</code> array to write
*
* @return If the operation is successfully completed, the method returns true, otherwise false
*
* @throws SerialPortException if exception occurred
*/
public int write(byte[] buffer) throws SerialPortException {
checkPortOpened("writeBytes()");
return serialInterface.write(portHandle, buffer);
}

/**
Expand Down Expand Up @@ -1392,4 +1413,5 @@ public void run() {
}
}
}

}

0 comments on commit 7ed987d

Please sign in to comment.