diff --git a/build.gradle b/build.gradle index fefb49b..2b250b0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'java' -apply plugin: 'cpp' +apply plugin: 'c' apply plugin: 'maven' apply plugin: 'eclipse' @@ -56,7 +56,7 @@ model { def jniHeadersDir = file("$buildDir/headers") task jniHeaders(dependsOn: compileJava) { - def outputFile = file("$jniHeadersDir/mimis.h") + def outputFile = file("$jniHeadersDir/pipe.h") inputs.files sourceSets.main.output outputs.file outputFile exec { @@ -64,7 +64,7 @@ task jniHeaders(dependsOn: compileJava) { args '-o', outputFile args '-classpath', sourceSets.main.output.classesDir args '-classpath', file("$buildDir/../bin") - args 'mimis.util.Native' + args 'pipe.Pipe' } } @@ -74,11 +74,11 @@ libraries { } all { binaries.all { - cppCompiler.args '-I' + jniHeadersDir - cppCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include" - cppCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include/win32" + cCompiler.args '-I' + jniHeadersDir + cCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include" + cCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include/win32" linker.args '-Wl,--kill-at', '-static-libgcc', '-static-libstdc++' - tasks.withType(CppCompile) { task -> + tasks.withType(CCompile) { task -> task.dependsOn jniHeaders } } diff --git a/src/pipe.c b/src/main/c/pipe.c similarity index 100% rename from src/pipe.c rename to src/main/c/pipe.c diff --git a/src/main/java/pipe/Pipe.java b/src/main/java/pipe/Pipe.java new file mode 100644 index 0000000..2a36d38 --- /dev/null +++ b/src/main/java/pipe/Pipe.java @@ -0,0 +1,56 @@ +package pipe; + +import com.github.boukefalos.jlibloader.Native; + +/** + * @author Vikram S Khatri vikram.khatri@us.ibm.com + */ +public class Pipe { + static final int ERROR_PIPE_CONNECTED = 535; + static final int ERROR_BROKEN_PIPE = 109; + static final int PIPE_ACCESS_DUPLEX = 0x00000003; + static final int PIPE_WAIT = 0x00000000; + + static { + Native.load("com.github.boukefalos", "jlibpipe"); + } + + public static final native int CreateNamedPipe( + String pipeName, + int ppenMode, + int pipeMode, + int maxInstances, + int outBufferSize, + int inBufferSize, + int defaultTimeOut, + int securityAttributes); + + public static final native boolean ConnectNamedPipe(int namedPipeHandle, int overlapped); + + public static final native int GetLastError(); + + public static final native boolean CloseHandle(int bbject); + + public static final native byte[] ReadFile(int file, int numberOfBytesToRead); + + public static final native int WriteFile(int file, byte[] buffer, int numberOfBytesToWrite); + + public static final native boolean FlushFileBuffers(int file); + + public static final native boolean DisconnectNamedPipe(int namedPipeHandle); + + public static final native int CreateFile( + String fileName, + int desiredAccess, + int shareMode, + int securityAttributes, + int creationDisposition, + int flagsAndAttributes, + int templateFile); + + public static final native boolean WaitNamedPipe(String namedPipeName, int timeOut); + + public static final native String FormatMessage(int errorCode); + + public static final native void Print(String message); +} diff --git a/src/pipe.h b/src/pipe.h deleted file mode 100644 index af398cb..0000000 --- a/src/pipe.h +++ /dev/null @@ -1,109 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class Pipes */ - -#ifndef _Included_pipe -#define _Included_pipe -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: Pipes - * Method: CreateNamedPipe - * Signature: (Ljava/lang/String;IIIIIII)I - */ -JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateNamedPipe - (JNIEnv *, jclass, jstring, jint, jint, jint, jint, jint, jint, jint); - -/* - * Class: Pipes - * Method: ConnectNamedPipe - * Signature: (II)Z - */ -JNIEXPORT jboolean JNICALL Java_pipe_Pipe_ConnectNamedPipe - (JNIEnv *, jclass, jint, jint); - -/* - * Class: Pipes - * Method: GetLastError - * Signature: ()I - */ -JNIEXPORT jint JNICALL Java_pipe_Pipe_GetLastError - (JNIEnv *, jclass); - -/* - * Class: Pipes - * Method: CloseHandle - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_pipe_Pipe_CloseHandle - (JNIEnv *, jclass, jint); - -/* - * Class: Pipes - * Method: ReadFile - * Signature: (II)[B - */ -JNIEXPORT jbyteArray JNICALL Java_pipe_Pipe_ReadFile - (JNIEnv *, jclass, jint, jint); - -/* - * Class: Pipes - * Method: WriteFile - * Signature: (I[BI)I - */ -JNIEXPORT jint JNICALL Java_pipe_Pipe_WriteFile - (JNIEnv *, jclass, jint, jbyteArray, jint); - -/* - * Class: Pipes - * Method: FlushFileBuffers - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_pipe_Pipe_FlushFileBuffers - (JNIEnv *, jclass, jint); - -/* - * Class: Pipes - * Method: DisconnectNamedPipe - * Signature: (I)Z - */ -JNIEXPORT jboolean JNICALL Java_pipe_Pipe_DisconnectNamedPipe - (JNIEnv *, jclass, jint); - -/* - * Class: Pipes - * Method: CreateFile - * Signature: (Ljava/lang/String;IIIIII)I - */ -JNIEXPORT jint JNICALL Java_pipe_Pipe_CreateFile - (JNIEnv *, jclass, jstring, jint, jint, jint, jint, jint, jint); - -/* - * Class: Pipes - * Method: WaitNamedPipe - * Signature: (Ljava/lang/String;I)Z - */ -JNIEXPORT jboolean JNICALL Java_pipe_Pipe_WaitNamedPipe - (JNIEnv *, jclass, jstring, jint); - -/* - * Class: Pipes - * Method: FormatMessage - * Signature: (I)Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_pipe_Pipe_FormatMessage - (JNIEnv *, jclass, jint); - -/* - * Class: Pipes - * Method: Print - * Signature: (Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL Java_pipe_Pipe_Print - (JNIEnv *, jclass, jstring); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/test/java/pipe/Client.java b/src/test/java/pipe/Client.java new file mode 100644 index 0000000..b36d882 --- /dev/null +++ b/src/test/java/pipe/Client.java @@ -0,0 +1,24 @@ +package pipe; + +import java.io.RandomAccessFile; + +public class Client { + public static void main(String[] args) { + try { + // Connect to the pipe + RandomAccessFile pipe = new RandomAccessFile("\\\\.\\pipe\\detest", "rw"); + String echoText = "Hello word\n"; + + // write to pipe + pipe.write(echoText.getBytes()); + + // read response + String echoResponse = pipe.readLine(); + System.out.println(echoResponse); + pipe.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/src/test/java/pipe/TestPipe.java b/src/test/java/pipe/TestPipe.java new file mode 100644 index 0000000..46865f9 --- /dev/null +++ b/src/test/java/pipe/TestPipe.java @@ -0,0 +1,86 @@ +package pipe; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +public class TestPipe { + + private int namedPipeHandle; + private String pipeName, srcFile; + private int pipeBuffer = 131072, fileBuffer = 8192; + + public TestPipe(String pipeName, String srcFile) { + this.pipeName = pipeName; + this.srcFile = srcFile; + } + + private void log(String message) { + System.out.println(message); + } + + private boolean createPipe() { + namedPipeHandle = Pipe.CreateNamedPipe( + pipeName, + Pipe.PIPE_ACCESS_DUPLEX, + Pipe.PIPE_WAIT, + 5, + pipeBuffer, + pipeBuffer, + 0xffffffff, + 0); + if (namedPipeHandle == -1) { + log("CreateNamedPipe failed for " + pipeName + " for error Message " + Pipe.FormatMessage(Pipe.GetLastError())); + } else { + log("Named Pipe " + pipeName + " created successfully Handle=" + namedPipeHandle); + } + return namedPipeHandle != -1; + } + + private boolean connectToPipe() { + log("Waiting for a client to connect to pipe " + pipeName); + boolean connected = Pipe.ConnectNamedPipe(namedPipeHandle, 0); + if (!connected) { + int lastError = Pipe.GetLastError(); + if (lastError == Pipe.ERROR_PIPE_CONNECTED) + connected = true; + } + log((connected ? "Connected to the pipe " : "Falied to connect to the pipe ") + pipeName); + return connected; + } + + public void runPipe() { + if (createPipe() && connectToPipe()) { + log("Client connected."); + try { + File f1 = new File(this.srcFile); + InputStream in = new FileInputStream(f1); + log("Sending data to the pipe"); + byte[] buf = new byte[fileBuffer]; + int len, bytesWritten; + while ((len = in.read(buf)) > 0) { + bytesWritten = Pipe.WriteFile(namedPipeHandle, buf, len); + log("Sent " + len + "/" + bytesWritten + " bytes to the pipe"); + if (bytesWritten == -1) { + int errorNumber = Pipe.GetLastError(); + log("Error Writing to pipe " + Pipe.FormatMessage(errorNumber)); + } + } + in.close(); + Pipe.FlushFileBuffers(namedPipeHandle); + Pipe.CloseHandle(namedPipeHandle); + Pipe.DisconnectNamedPipe(namedPipeHandle); + log("Writing to the pipe completed."); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public static void main(String[] args) { + String pipeName = "\\\\.\\pipe\\detest"; + String fileName = "C:\\Users\\Rik\\Music\\Artists\\+44\\When Your Heart Stops Beating\\+44 - 155.mp3"; + TestPipe testPipe = new TestPipe(pipeName, fileName); + testPipe.runPipe(); + } +}