re-implement System.getProperty to separate vm-specific properties from others

This commit is contained in:
Joel Dice 2007-08-27 07:46:17 -06:00
parent 493667a6cc
commit b8de552797
7 changed files with 105 additions and 30 deletions

View File

@ -6,6 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "jni.h" #include "jni.h"
#include "jni-util.h"
#undef JNIEXPORT #undef JNIEXPORT
#define JNIEXPORT __attribute__ ((visibility("default"))) #define JNIEXPORT __attribute__ ((visibility("default")))
@ -36,16 +37,6 @@
namespace { namespace {
inline void
throwNew(JNIEnv* e, const char* class_, const char* message)
{
jclass c = e->FindClass(class_);
if (c) {
e->ThrowNew(c, message);
e->DeleteLocalRef(c);
}
}
inline bool inline bool
exists(const char* path) exists(const char* path)
{ {

View File

@ -3,26 +3,30 @@
#include "time.h" #include "time.h"
#include "string.h" #include "string.h"
#include "jni.h" #include "jni.h"
#include "jni-util.h"
#undef JNIEXPORT #undef JNIEXPORT
#define JNIEXPORT __attribute__ ((visibility("default"))) #define JNIEXPORT __attribute__ ((visibility("default")))
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jstring key) Java_java_lang_System_getProperty(JNIEnv* e, jclass, jint code)
{ {
jstring value = 0; enum {
LineSeparator = 100,
OsName = 101
};
const char* chars = e->GetStringUTFChars(key, 0); switch (code) {
if (chars) { case LineSeparator:
if (strcmp(chars, "line.separator") == 0) { return e->NewStringUTF("\n");
value = e->NewStringUTF("\n");
} else if (strcmp(chars, "os.name") == 0) {
value = e->NewStringUTF("posix");
}
e->ReleaseStringUTFChars(key, chars);
}
return value; case OsName:
return e->NewStringUTF("posix");
default:
throwNew(e, "java/lang/RuntimeException", 0);
return 0;
}
} }
extern "C" JNIEXPORT jlong JNICALL extern "C" JNIEXPORT jlong JNICALL

View File

@ -9,6 +9,12 @@ import java.io.FileOutputStream;
import java.io.FileDescriptor; import java.io.FileDescriptor;
public abstract class System { public abstract class System {
private static final int Unknown = 0;
private static final int JavaClassPath = 1;
private static final int LineSeparator = 100;
private static final int OsName = 101;
static { static {
loadLibrary("natives"); loadLibrary("natives");
} }
@ -25,7 +31,28 @@ public abstract class System {
public static native void arraycopy(Object src, int srcOffset, Object dst, public static native void arraycopy(Object src, int srcOffset, Object dst,
int dstOffset, int length); int dstOffset, int length);
public static native String getProperty(String name); public static String getProperty(String name) {
int code = Unknown;
if (name.equals("java.class.path")) {
code = JavaClassPath;
} else if (name.equals("line.separator")) {
code = LineSeparator;
} else if (name.equals("os.name")) {
code = OsName;
}
if (code == Unknown) {
return null;
} else if (code == JavaClassPath) {
return getVMProperty(code);
} else {
return getProperty(code);
}
}
private static native String getProperty(int code);
private static native String getVMProperty(int code);
public static native long currentTimeMillis(); public static native long currentTimeMillis();

18
classpath/jni-util.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef JNI_UTIL
#define JNI_UTIL
namespace {
inline void
throwNew(JNIEnv* e, const char* class_, const char* message)
{
jclass c = e->FindClass(class_);
if (c) {
e->ThrowNew(c, message);
e->DeleteLocalRef(c);
}
}
} // namespace
#endif//JNI_UTIL

View File

@ -331,6 +331,23 @@ String_intern(Thread* t, jobject this_)
return pushReference(t, intern(t, *this_)); return pushReference(t, intern(t, *this_));
} }
jstring
System_getVMProperty(Thread* t, jclass, jint code)
{
enum {
JavaClassPath = 1
};
switch (code) {
case JavaClassPath:
return pushReference(t, makeString(t, "%s", t->vm->finder->path()));
default:
t->exception = makeRuntimeException(t, 0);
return 0;
}
}
void void
System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst, System_arraycopy(Thread* t, jclass, jobject src, jint srcOffset, jobject dst,
jint dstOffset, jint length) jint dstOffset, jint length)
@ -584,6 +601,8 @@ populateBuiltinMap(Thread* t, object map)
{ "Java_java_lang_ClassLoader_defineClass", { "Java_java_lang_ClassLoader_defineClass",
reinterpret_cast<void*>(::ClassLoader_defineClass) }, reinterpret_cast<void*>(::ClassLoader_defineClass) },
{ "Java_java_lang_System_getVMProperty",
reinterpret_cast<void*>(::System_getVMProperty) },
{ "Java_java_lang_System_arraycopy", { "Java_java_lang_System_arraycopy",
reinterpret_cast<void*>(::System_arraycopy) }, reinterpret_cast<void*>(::System_arraycopy) },

View File

@ -23,6 +23,15 @@ append(System* s, const char* a, const char* b, const char* c)
return p; return p;
} }
const char*
copy(System* s, const char* a)
{
unsigned al = strlen(a);
char* p = static_cast<char*>(s->allocate(al + 1));
memcpy(p, a, al + 1);
return p;
}
const char** const char**
parsePath(System* s, const char* path) parsePath(System* s, const char* path)
{ {
@ -77,7 +86,8 @@ class MyFinder: public Finder {
public: public:
MyFinder(System* system, const char* path): MyFinder(System* system, const char* path):
system(system), system(system),
path(parsePath(system, path)) path_(parsePath(system, path)),
pathString(copy(system, path))
{ } { }
class Data: public Finder::Data { class Data: public Finder::Data {
@ -111,7 +121,7 @@ class MyFinder: public Finder {
virtual Data* find(const char* name) { virtual Data* find(const char* name) {
Data* d = new (system->allocate(sizeof(Data))) Data(system, 0, 0); Data* d = new (system->allocate(sizeof(Data))) Data(system, 0, 0);
for (const char** p = path; *p; ++p) { for (const char** p = path_; *p; ++p) {
const char* file = append(system, *p, "/", name); const char* file = append(system, *p, "/", name);
int fd = open(file, O_RDONLY); int fd = open(file, O_RDONLY);
system->free(file); system->free(file);
@ -135,7 +145,7 @@ class MyFinder: public Finder {
} }
virtual bool exists(const char* name) { virtual bool exists(const char* name) {
for (const char** p = path; *p; ++p) { for (const char** p = path_; *p; ++p) {
const char* file = append(system, *p, "/", name); const char* file = append(system, *p, "/", name);
struct stat s; struct stat s;
int r = stat(file, &s); int r = stat(file, &s);
@ -148,17 +158,22 @@ class MyFinder: public Finder {
return false; return false;
} }
virtual const char* path() {
return pathString;
}
virtual void dispose() { virtual void dispose() {
for (const char** p = path; *p; ++p) { for (const char** p = path_; *p; ++p) {
system->free(*p); system->free(*p);
} }
system->free(path); system->free(path_);
system->free(pathString);
system->free(this); system->free(this);
} }
System* system; System* system;
const char** path; const char** path_;
const char* pathString;
}; };
} // namespace } // namespace

View File

@ -19,6 +19,7 @@ class Finder {
virtual ~Finder() { } virtual ~Finder() { }
virtual Data* find(const char* name) = 0; virtual Data* find(const char* name) = 0;
virtual bool exists(const char* name) = 0; virtual bool exists(const char* name) = 0;
virtual const char* path() = 0;
virtual void dispose() = 0; virtual void dispose() = 0;
}; };