diff --git a/readme.md b/readme.md index 7552cab..0a942fc 100755 --- a/readme.md +++ b/readme.md @@ -114,3 +114,5 @@ You can run `$INSTALL_DIR/bin/native-platform` to run the test application. * Improve error message when unsupported capability is used. * Initial release. * Use fully decomposed form for unicode file names on hfs+ filesystems. +* Handle string encoding for file system details +* Handle string encoding for system info diff --git a/src/main/cpp/generic.cpp b/src/main/cpp/generic.cpp index 9d2882e..ea18805 100755 --- a/src/main/cpp/generic.cpp +++ b/src/main/cpp/generic.cpp @@ -17,5 +17,5 @@ void mark_failed_with_code(JNIEnv *env, const char* message, int error_code, job JNIEXPORT jint JNICALL Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getVersion(JNIEnv *env, jclass target) { - return 5; + return 6; } diff --git a/src/main/cpp/posix.cpp b/src/main/cpp/posix.cpp index 5da2a68..72deb3a 100755 --- a/src/main/cpp/posix.cpp +++ b/src/main/cpp/posix.cpp @@ -56,21 +56,21 @@ Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getSystemIn */ JNIEXPORT void JNICALL -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); +Java_net_rubygrapefruit_platform_internal_jni_PosixFileFunctions_chmod(JNIEnv *env, jclass target, jbyteArray path, jint mode, jobject result) { + jbyte* pathUtf8 = env->GetByteArrayElements(path, NULL); + int retval = chmod((const char*)pathUtf8, mode); + env->ReleaseByteArrayElements(path, pathUtf8, JNI_ABORT); if (retval != 0) { mark_failed_with_errno(env, "could not chmod file", result); } } JNIEXPORT void JNICALL -Java_net_rubygrapefruit_platform_internal_jni_PosixFileFunctions_stat(JNIEnv *env, jclass target, jstring path, jobject dest, jobject result) { +Java_net_rubygrapefruit_platform_internal_jni_PosixFileFunctions_stat(JNIEnv *env, jclass target, jbyteArray path, jobject dest, jobject result) { struct stat fileInfo; - const char* pathUtf8 = env->GetStringUTFChars(path, NULL); - int retval = stat(pathUtf8, &fileInfo); - env->ReleaseStringUTFChars(path, pathUtf8); + jbyte* pathUtf8 = env->GetByteArrayElements(path, NULL); + int retval = stat((const char*)pathUtf8, &fileInfo); + env->ReleaseByteArrayElements(path, pathUtf8, JNI_ABORT); if (retval != 0) { mark_failed_with_errno(env, "could not stat file", result); return; diff --git a/src/main/java/net/rubygrapefruit/platform/internal/DefaultPosixFile.java b/src/main/java/net/rubygrapefruit/platform/internal/DefaultPosixFile.java index 7c0e806..3582924 100755 --- a/src/main/java/net/rubygrapefruit/platform/internal/DefaultPosixFile.java +++ b/src/main/java/net/rubygrapefruit/platform/internal/DefaultPosixFile.java @@ -1,29 +1,57 @@ -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; - } -} +package net.rubygrapefruit.platform.internal; + +import net.rubygrapefruit.platform.NativeException; +import net.rubygrapefruit.platform.PosixFile; +import net.rubygrapefruit.platform.internal.jni.NativeLibraryFunctions; +import net.rubygrapefruit.platform.internal.jni.PosixFileFunctions; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +public class DefaultPosixFile implements PosixFile { + private final String characterEncoding; + + public DefaultPosixFile() { + MutableSystemInfo systemInfo = new MutableSystemInfo(); + FunctionResult result = new FunctionResult(); + NativeLibraryFunctions.getSystemInfo(systemInfo, result); + if (result.isFailed()) { + throw new NativeException(String.format("Could not fetch system information: %s", + result.getMessage())); + } + this.characterEncoding = systemInfo.characterEncoding; + } + + @Override + public void setMode(File file, int perms) { + FunctionResult result = new FunctionResult(); + PosixFileFunctions.chmod(encode(file), 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(encode(file), 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 byte[] encode(File file) { + byte[] encodedName; + try { + encodedName = file.getPath().getBytes(characterEncoding); + } catch (UnsupportedEncodingException e) { + throw new NativeException(String.format("Could not encode path for file '%s' using encoding %s.", file.getName(), characterEncoding)); + } + byte[] buffer = new byte[encodedName.length + 1]; + System.arraycopy(encodedName, 0, buffer, 0, encodedName.length); + buffer[buffer.length - 1] = 0; + return buffer; + } +} diff --git a/src/main/java/net/rubygrapefruit/platform/internal/Platform.java b/src/main/java/net/rubygrapefruit/platform/internal/Platform.java index 0497960..33d69c8 100755 --- a/src/main/java/net/rubygrapefruit/platform/internal/Platform.java +++ b/src/main/java/net/rubygrapefruit/platform/internal/Platform.java @@ -85,7 +85,6 @@ public abstract class Platform { throw new NativeException(String.format("Could not fetch system information: %s", result.getMessage())); } - System.out.println("=> CHARACTER ENCODING: " + systemInfo.characterEncoding); return type.cast(systemInfo); } return super.get(type); diff --git a/src/main/java/net/rubygrapefruit/platform/internal/jni/NativeLibraryFunctions.java b/src/main/java/net/rubygrapefruit/platform/internal/jni/NativeLibraryFunctions.java index 96dd22c..bbeeb43 100755 --- a/src/main/java/net/rubygrapefruit/platform/internal/jni/NativeLibraryFunctions.java +++ b/src/main/java/net/rubygrapefruit/platform/internal/jni/NativeLibraryFunctions.java @@ -4,7 +4,7 @@ import net.rubygrapefruit.platform.internal.FunctionResult; import net.rubygrapefruit.platform.internal.MutableSystemInfo; public class NativeLibraryFunctions { - public static final int VERSION = 5; + public static final int VERSION = 6; public static native int getVersion(); diff --git a/src/main/java/net/rubygrapefruit/platform/internal/jni/PosixFileFunctions.java b/src/main/java/net/rubygrapefruit/platform/internal/jni/PosixFileFunctions.java index 695a707..ae02e02 100755 --- a/src/main/java/net/rubygrapefruit/platform/internal/jni/PosixFileFunctions.java +++ b/src/main/java/net/rubygrapefruit/platform/internal/jni/PosixFileFunctions.java @@ -1,10 +1,10 @@ -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); -} +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(byte[] file, int perms, FunctionResult result); + + public static native void stat(byte[] file, FileStat stat, FunctionResult result); +}