Moved some classes around.

This commit is contained in:
Adam Murdoch
2012-08-04 13:32:41 +10:00
parent a1c46d3dfa
commit e9b300f610
17 changed files with 302 additions and 252 deletions

View File

@@ -16,6 +16,6 @@ void mark_failed_with_code(JNIEnv *env, const char* message, int error_code, job
}
JNIEXPORT jint JNICALL
Java_net_rubygrapefruit_platform_internal_NativeLibraryFunctions_getVersion(JNIEnv *env, jclass target) {
Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getVersion(JNIEnv *env, jclass target) {
return 2;
}

View File

@@ -23,7 +23,7 @@ void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
*/
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_PosixFileFunctions_chmod(JNIEnv *env, jclass target, jstring path, jint mode, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_PosixFileFunctions_chmod(JNIEnv *env, jclass target, jstring path, jint mode, jobject result) {
const char* pathUtf8 = env->GetStringUTFChars(path, NULL);
int retval = chmod(pathUtf8, mode);
env->ReleaseStringUTFChars(path, pathUtf8);
@@ -33,7 +33,7 @@ Java_net_rubygrapefruit_platform_internal_PosixFileFunctions_chmod(JNIEnv *env,
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_PosixFileFunctions_stat(JNIEnv *env, jclass target, jstring path, jobject dest, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_PosixFileFunctions_stat(JNIEnv *env, jclass target, jstring path, jobject dest, jobject result) {
struct stat fileInfo;
const char* pathUtf8 = env->GetStringUTFChars(path, NULL);
int retval = stat(pathUtf8, &fileInfo);
@@ -52,7 +52,7 @@ Java_net_rubygrapefruit_platform_internal_PosixFileFunctions_stat(JNIEnv *env, j
*/
JNIEXPORT jint JNICALL
Java_net_rubygrapefruit_platform_internal_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
return getpid();
}
@@ -61,7 +61,7 @@ Java_net_rubygrapefruit_platform_internal_PosixProcessFunctions_getPid(JNIEnv *e
*/
JNIEXPORT jboolean JNICALL
Java_net_rubygrapefruit_platform_internal_PosixTerminalFunctions_isatty(JNIEnv *env, jclass target, jint output) {
Java_net_rubygrapefruit_platform_internal_jni_PosixTerminalFunctions_isatty(JNIEnv *env, jclass target, jint output) {
switch (output) {
case 0:
case 1:
@@ -72,7 +72,7 @@ Java_net_rubygrapefruit_platform_internal_PosixTerminalFunctions_isatty(JNIEnv *
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_PosixTerminalFunctions_getTerminalSize(JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_PosixTerminalFunctions_getTerminalSize(JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
struct winsize screen_size;
int retval = ioctl(output+1, TIOCGWINSZ, &screen_size);
if (retval != 0) {
@@ -109,7 +109,7 @@ void write_capability(JNIEnv *env, const char* capability, jobject result) {
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_TerminfoFunctions_initTerminal(JNIEnv *env, jclass target, jint output, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_TerminfoFunctions_initTerminal(JNIEnv *env, jclass target, jint output, jobject result) {
if (!isatty(output+1)) {
mark_failed_with_message(env, "not a terminal", result);
return;
@@ -129,17 +129,17 @@ Java_net_rubygrapefruit_platform_internal_TerminfoFunctions_initTerminal(JNIEnv
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_TerminfoFunctions_bold(JNIEnv *env, jclass target, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_TerminfoFunctions_bold(JNIEnv *env, jclass target, jobject result) {
write_capability(env, "md", result);
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_TerminfoFunctions_reset(JNIEnv *env, jclass target, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_TerminfoFunctions_reset(JNIEnv *env, jclass target, jobject result) {
write_capability(env, "me", result);
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_TerminfoFunctions_foreground(JNIEnv *env, jclass target, jint color, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_TerminfoFunctions_foreground(JNIEnv *env, jclass target, jint color, jobject result) {
char* capability = tgetstr((char*)"AF", NULL);
if (capability == NULL) {
mark_failed_with_message(env, "unknown terminal capability", result);

View File

@@ -16,7 +16,7 @@ void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
*/
JNIEXPORT jint JNICALL
Java_net_rubygrapefruit_platform_internal_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
return GetCurrentProcessId();
}
@@ -34,7 +34,7 @@ HANDLE getHandle(JNIEnv *env, int output, jobject result) {
}
JNIEXPORT jboolean JNICALL
Java_net_rubygrapefruit_platform_internal_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
@@ -51,7 +51,7 @@ Java_net_rubygrapefruit_platform_internal_WindowsConsoleFunctions_isConsole(JNIE
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_WindowsConsoleFunctions_getConsoleSize (JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_getConsoleSize (JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {

View File

@@ -1,10 +1,10 @@
package net.rubygrapefruit.platform;
import net.rubygrapefruit.platform.internal.*;
import net.rubygrapefruit.platform.internal.jni.NativeLibraryFunctions;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
/**
* Provides access to the native integrations. Use {@link #get(Class)} to load a particular integration.
@@ -56,192 +56,4 @@ public class Native {
throw new UnsupportedOperationException(String.format("Cannot load unsupported native integration %s.",
type.getName()));
}
private static class DefaultPosixFile implements PosixFile {
@Override
public void setMode(File file, int perms) {
FunctionResult result = new FunctionResult();
PosixFileFunctions.chmod(file.getPath(), perms, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not set UNIX mode on %s: %s", file, result.getMessage()));
}
}
@Override
public int getMode(File file) {
FunctionResult result = new FunctionResult();
FileStat stat = new FileStat();
PosixFileFunctions.stat(file.getPath(), stat, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not get UNIX mode on %s: %s", file, result.getMessage()));
}
return stat.mode;
}
}
private static class DefaultProcess implements Process {
@Override
public int getProcessId() throws NativeException {
return PosixProcessFunctions.getPid();
}
}
private static class TerminfoTerminalAccess implements TerminalAccess {
private static Output currentlyOpen;
@Override
public boolean isTerminal(Output output) {
return PosixTerminalFunctions.isatty(output.ordinal());
}
@Override
public Terminal getTerminal(Output output) {
if (currentlyOpen != null) {
throw new UnsupportedOperationException("Currently only one output can be used as a terminal.");
}
DefaultTerminal terminal = new DefaultTerminal(output);
terminal.init();
currentlyOpen = output;
return terminal;
}
}
private static class DefaultTerminal implements Terminal {
private final TerminalAccess.Output output;
private final PrintStream stream;
private Color foreground;
public DefaultTerminal(TerminalAccess.Output output) {
this.output = output;
stream = output == TerminalAccess.Output.Stdout ? System.out : System.err;
}
public void init() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.initTerminal(output.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not open terminal: %s", result.getMessage()));
}
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
reset();
}
});
}
@Override
public TerminalSize getTerminalSize() {
MutableTerminalSize terminalSize = new MutableTerminalSize();
FunctionResult result = new FunctionResult();
PosixTerminalFunctions.getTerminalSize(output.ordinal(), terminalSize, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not get terminal size: %s", result.getMessage()));
}
return terminalSize;
}
@Override
public Terminal foreground(Color color) {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.foreground(color.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch foreground color: %s", result.getMessage()));
}
foreground = color;
return this;
}
@Override
public Terminal bold() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.bold(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch to bold mode: %s", result.getMessage()));
}
return this;
}
@Override
public Terminal normal() {
reset();
if (foreground != null) {
foreground(foreground);
}
return this;
}
@Override
public Terminal reset() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.reset(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not reset terminal: %s", result.getMessage()));
}
return this;
}
}
private static class WindowsTerminalAccess implements TerminalAccess {
@Override
public boolean isTerminal(Output output) {
FunctionResult result = new FunctionResult();
boolean console = WindowsConsoleFunctions.isConsole(output.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not determine if %s is a console: %s", output,
result.getMessage()));
}
return console;
}
@Override
public Terminal getTerminal(Output output) {
return new WindowsTerminal(output);
}
}
private static class WindowsTerminal implements Terminal {
private final TerminalAccess.Output output;
public WindowsTerminal(TerminalAccess.Output output) {
this.output = output;
}
@Override
public TerminalSize getTerminalSize() {
FunctionResult result = new FunctionResult();
MutableTerminalSize size = new MutableTerminalSize();
WindowsConsoleFunctions.getConsoleSize(output.ordinal(), size, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not determine terminal size: %s", result.getMessage()));
}
return size;
}
@Override
public Terminal bold() {
throw new UnsupportedOperationException();
}
@Override
public Terminal foreground(Color color) {
throw new UnsupportedOperationException();
}
@Override
public Terminal normal() {
throw new UnsupportedOperationException();
}
@Override
public Terminal reset() {
throw new UnsupportedOperationException();
}
}
}

View File

@@ -0,0 +1,29 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.NativeException;
import net.rubygrapefruit.platform.PosixFile;
import net.rubygrapefruit.platform.internal.jni.PosixFileFunctions;
import java.io.File;
public class DefaultPosixFile implements PosixFile {
@Override
public void setMode(File file, int perms) {
FunctionResult result = new FunctionResult();
PosixFileFunctions.chmod(file.getPath(), perms, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not set UNIX mode on %s: %s", file, result.getMessage()));
}
}
@Override
public int getMode(File file) {
FunctionResult result = new FunctionResult();
FileStat stat = new FileStat();
PosixFileFunctions.stat(file.getPath(), stat, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not get UNIX mode on %s: %s", file, result.getMessage()));
}
return stat.mode;
}
}

View File

@@ -0,0 +1,11 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.*;
import net.rubygrapefruit.platform.internal.jni.PosixProcessFunctions;
public class DefaultProcess implements net.rubygrapefruit.platform.Process {
@Override
public int getProcessId() throws NativeException {
return PosixProcessFunctions.getPid();
}
}

View File

@@ -0,0 +1,90 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.NativeException;
import net.rubygrapefruit.platform.Terminal;
import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.TerminalSize;
import net.rubygrapefruit.platform.internal.jni.PosixTerminalFunctions;
import net.rubygrapefruit.platform.internal.jni.TerminfoFunctions;
import java.io.PrintStream;
public class DefaultTerminal implements Terminal {
private final TerminalAccess.Output output;
private final PrintStream stream;
private Color foreground;
public DefaultTerminal(TerminalAccess.Output output) {
this.output = output;
stream = output == TerminalAccess.Output.Stdout ? System.out : System.err;
}
public void init() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.initTerminal(output.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not open terminal: %s", result.getMessage()));
}
Runtime.getRuntime().addShutdownHook(new Thread(){
@Override
public void run() {
reset();
}
});
}
@Override
public TerminalSize getTerminalSize() {
MutableTerminalSize terminalSize = new MutableTerminalSize();
FunctionResult result = new FunctionResult();
PosixTerminalFunctions.getTerminalSize(output.ordinal(), terminalSize, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not get terminal size: %s", result.getMessage()));
}
return terminalSize;
}
@Override
public Terminal foreground(Color color) {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.foreground(color.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch foreground color: %s", result.getMessage()));
}
foreground = color;
return this;
}
@Override
public Terminal bold() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.bold(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not switch to bold mode: %s", result.getMessage()));
}
return this;
}
@Override
public Terminal normal() {
reset();
if (foreground != null) {
foreground(foreground);
}
return this;
}
@Override
public Terminal reset() {
stream.flush();
FunctionResult result = new FunctionResult();
TerminfoFunctions.reset(result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not reset terminal: %s", result.getMessage()));
}
return this;
}
}

View File

@@ -0,0 +1,27 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.Terminal;
import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.internal.jni.PosixTerminalFunctions;
public class TerminfoTerminalAccess implements TerminalAccess {
private static Output currentlyOpen;
@Override
public boolean isTerminal(Output output) {
return PosixTerminalFunctions.isatty(output.ordinal());
}
@Override
public Terminal getTerminal(Output output) {
if (currentlyOpen != null) {
throw new UnsupportedOperationException("Currently only one output can be used as a terminal.");
}
DefaultTerminal terminal = new DefaultTerminal(output);
terminal.init();
currentlyOpen = output;
return terminal;
}
}

View File

@@ -0,0 +1,46 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.NativeException;
import net.rubygrapefruit.platform.Terminal;
import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.TerminalSize;
import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions;
public class WindowsTerminal implements Terminal {
private final TerminalAccess.Output output;
public WindowsTerminal(TerminalAccess.Output output) {
this.output = output;
}
@Override
public TerminalSize getTerminalSize() {
FunctionResult result = new FunctionResult();
MutableTerminalSize size = new MutableTerminalSize();
WindowsConsoleFunctions.getConsoleSize(output.ordinal(), size, result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not determine terminal size: %s", result.getMessage()));
}
return size;
}
@Override
public Terminal bold() {
throw new UnsupportedOperationException();
}
@Override
public Terminal foreground(Color color) {
throw new UnsupportedOperationException();
}
@Override
public Terminal normal() {
throw new UnsupportedOperationException();
}
@Override
public Terminal reset() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,24 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.NativeException;
import net.rubygrapefruit.platform.Terminal;
import net.rubygrapefruit.platform.TerminalAccess;
import net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions;
public class WindowsTerminalAccess implements TerminalAccess {
@Override
public boolean isTerminal(Output output) {
FunctionResult result = new FunctionResult();
boolean console = WindowsConsoleFunctions.isConsole(output.ordinal(), result);
if (result.isFailed()) {
throw new NativeException(String.format("Could not determine if %s is a console: %s", output,
result.getMessage()));
}
return console;
}
@Override
public Terminal getTerminal(Output output) {
return new WindowsTerminal(output);
}
}

View File

@@ -1,7 +1,7 @@
package net.rubygrapefruit.platform.internal;
public class NativeLibraryFunctions {
public static final int VERSION = 2;
public static native int getVersion();
}
package net.rubygrapefruit.platform.internal.jni;
public class NativeLibraryFunctions {
public static final int VERSION = 2;
public static native int getVersion();
}

View File

@@ -1,7 +1,10 @@
package net.rubygrapefruit.platform.internal;
public class PosixFileFunctions {
public static native void chmod(String file, int perms, FunctionResult result);
public static native void stat(String file, FileStat stat, FunctionResult result);
}
package net.rubygrapefruit.platform.internal.jni;
import net.rubygrapefruit.platform.internal.FileStat;
import net.rubygrapefruit.platform.internal.FunctionResult;
public class PosixFileFunctions {
public static native void chmod(String file, int perms, FunctionResult result);
public static native void stat(String file, FileStat stat, FunctionResult result);
}

View File

@@ -1,5 +1,5 @@
package net.rubygrapefruit.platform.internal;
public class PosixProcessFunctions {
public static native int getPid();
}
package net.rubygrapefruit.platform.internal.jni;
public class PosixProcessFunctions {
public static native int getPid();
}

View File

@@ -1,7 +1,10 @@
package net.rubygrapefruit.platform.internal;
public class PosixTerminalFunctions {
public static native boolean isatty(int filedes);
public static native void getTerminalSize(int filedes, MutableTerminalSize size, FunctionResult result);
}
package net.rubygrapefruit.platform.internal.jni;
import net.rubygrapefruit.platform.internal.FunctionResult;
import net.rubygrapefruit.platform.internal.MutableTerminalSize;
public class PosixTerminalFunctions {
public static native boolean isatty(int filedes);
public static native void getTerminalSize(int filedes, MutableTerminalSize size, FunctionResult result);
}

View File

@@ -1,17 +1,19 @@
package net.rubygrapefruit.platform.internal;
public class TerminfoFunctions {
/**
* Sets up terminal info and switches output to normal mode.
*/
public static native void initTerminal(int filedes, FunctionResult result);
public static native void bold(FunctionResult result);
public static native void reset(FunctionResult result);
/**
* Set the foreground color to the given ansi color.
*/
public static native void foreground(int ansiColor, FunctionResult result);
}
package net.rubygrapefruit.platform.internal.jni;
import net.rubygrapefruit.platform.internal.FunctionResult;
public class TerminfoFunctions {
/**
* Sets up terminal info and switches output to normal mode.
*/
public static native void initTerminal(int filedes, FunctionResult result);
public static native void bold(FunctionResult result);
public static native void reset(FunctionResult result);
/**
* Set the foreground color to the given ansi color.
*/
public static native void foreground(int ansiColor, FunctionResult result);
}

View File

@@ -1,4 +1,7 @@
package net.rubygrapefruit.platform.internal;
package net.rubygrapefruit.platform.internal.jni;
import net.rubygrapefruit.platform.internal.FunctionResult;
import net.rubygrapefruit.platform.internal.MutableTerminalSize;
public class WindowsConsoleFunctions {
public static native boolean isConsole(int filedes, FunctionResult result);