From 97aaa419b468ed9bf7cc61c86a75a5d74fab8937 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 24 Jul 2007 18:34:45 -0600 Subject: [PATCH] quick sketch of java/io/* --- classpath/java/io/BufferedInputStream.java | 68 +++++++++++++++++++++ classpath/java/io/BufferedOutputStream.java | 51 ++++++++++++++++ classpath/java/io/FileDescriptor.java | 17 ++++++ classpath/java/io/FileInputStream.java | 15 +++++ classpath/java/io/FileOutputStream.java | 16 +++++ classpath/java/io/IOException.java | 19 ++++++ classpath/java/io/InputStream.java | 27 ++++++++ classpath/java/io/OutputStream.java | 19 ++++++ classpath/java/io/PrintStream.java | 51 ++++++++++++++++ classpath/java/lang/String.java | 24 ++++++++ classpath/java/lang/System.cpp | 11 ---- classpath/java/lang/System.java | 29 +++++---- makefile | 2 +- src/machine.h | 2 +- test/Reflection.java | 2 +- 15 files changed, 327 insertions(+), 26 deletions(-) create mode 100644 classpath/java/io/BufferedInputStream.java create mode 100644 classpath/java/io/BufferedOutputStream.java create mode 100644 classpath/java/io/FileDescriptor.java create mode 100644 classpath/java/io/FileInputStream.java create mode 100644 classpath/java/io/FileOutputStream.java create mode 100644 classpath/java/io/IOException.java create mode 100644 classpath/java/io/InputStream.java create mode 100644 classpath/java/io/OutputStream.java create mode 100644 classpath/java/io/PrintStream.java diff --git a/classpath/java/io/BufferedInputStream.java b/classpath/java/io/BufferedInputStream.java new file mode 100644 index 0000000000..7ad13e0f0f --- /dev/null +++ b/classpath/java/io/BufferedInputStream.java @@ -0,0 +1,68 @@ +package java.io; + +public class BufferedInputStream extends InputStream { + private final InputStream in; + private final byte[] buffer; + private int position; + private int limit; + + public BufferedInputStream(InputStream in, int size) { + this.in = in; + this.buffer = new byte[size]; + } + + public BufferedInputStream(InputStream in) { + this(in, 32); + } + + private void fill() throws IOException { + position = 0; + limit = in.read(buffer); + } + + public int read() throws IOException { + if (position >= limit) { + fill(); + if (limit == -1) { + return -1; + } + } + + return buffer[position++]; + } + + public int read(byte[] b, int offset, int length) throws IOException { + int count = 0; + + if (position < limit) { + int remaining = limit - position; + if (remaining > length) { + remaining = length; + } + + System.arraycopy(buffer, position, b, offset, remaining); + + count += remaining; + position += remaining; + offset += remaining; + length -= remaining; + } + + if (length > 0) { + int c = in.read(b, offset, length); + if (c == -1) { + if (count == 0) { + count = -1; + } + } else { + count += c; + } + } + + return count; + } + + public void close() throws IOException { + in.close(); + } +} diff --git a/classpath/java/io/BufferedOutputStream.java b/classpath/java/io/BufferedOutputStream.java new file mode 100644 index 0000000000..e3abf92837 --- /dev/null +++ b/classpath/java/io/BufferedOutputStream.java @@ -0,0 +1,51 @@ +package java.io; + +public class BufferedOutputStream extends OutputStream { + private final OutputStream out; + private final byte[] buffer; + private int position; + + public BufferedOutputStream(OutputStream out, int size) { + this.out = out; + this.buffer = new byte[size]; + } + + public BufferedOutputStream(OutputStream out) { + this(out, 4096); + } + + private void drain() throws IOException { + if (position > 0) { + out.write(buffer, 0, position); + position = 0; + } + } + + public void write(int c) throws IOException { + if (position >= buffer.length) { + drain(); + } + + buffer[position++] = (byte) (c & 0xFF); + } + + public void write(byte[] b, int offset, int length) throws IOException { + if (length > buffer.length - position) { + drain(); + out.write(b, offset, length); + } else { + System.arraycopy(b, offset, buffer, position, length); + position += length; + } + } + + public void flush() throws IOException { + drain(); + out.flush(); + } + + public void close() throws IOException { + flush(); + out.close(); + } +} diff --git a/classpath/java/io/FileDescriptor.java b/classpath/java/io/FileDescriptor.java new file mode 100644 index 0000000000..357564ed6d --- /dev/null +++ b/classpath/java/io/FileDescriptor.java @@ -0,0 +1,17 @@ +package java.io; + +public class FileDescriptor { + public static final FileDescriptor in = new FileDescriptor(0); + public static final FileDescriptor out = new FileDescriptor(1); + public static final FileDescriptor err = new FileDescriptor(2); + + private final int value; + + private FileDescriptor(int value) { + this.value = value; + } + + public FileDescriptor() { + this(-1); + } +} diff --git a/classpath/java/io/FileInputStream.java b/classpath/java/io/FileInputStream.java new file mode 100644 index 0000000000..33f1a895e9 --- /dev/null +++ b/classpath/java/io/FileInputStream.java @@ -0,0 +1,15 @@ +package java.io; + +public class FileInputStream extends InputStream { + private final FileDescriptor fd; + + public FileInputStream(FileDescriptor fd) { + this.fd = fd; + } + + public native int read() throws IOException; + + public native int read(byte[] b, int offset, int length) throws IOException; + + public native void close() throws IOException; +} diff --git a/classpath/java/io/FileOutputStream.java b/classpath/java/io/FileOutputStream.java new file mode 100644 index 0000000000..6dec42f6ca --- /dev/null +++ b/classpath/java/io/FileOutputStream.java @@ -0,0 +1,16 @@ +package java.io; + +public class FileOutputStream extends OutputStream { + private final FileDescriptor fd; + + public FileOutputStream(FileDescriptor fd) { + this.fd = fd; + } + + public native void write(int c) throws IOException; + + public native void write(byte[] b, int offset, int length) + throws IOException; + + public native void close() throws IOException; +} diff --git a/classpath/java/io/IOException.java b/classpath/java/io/IOException.java new file mode 100644 index 0000000000..e48412b5f7 --- /dev/null +++ b/classpath/java/io/IOException.java @@ -0,0 +1,19 @@ +package java.io; + +public class IOException extends Exception { + public IOException(String message, Throwable cause) { + super(message, cause); + } + + public IOException(String message) { + this(message, null); + } + + public IOException(Throwable cause) { + this(null, cause); + } + + public IOException() { + this(null, null); + } +} diff --git a/classpath/java/io/InputStream.java b/classpath/java/io/InputStream.java new file mode 100644 index 0000000000..441586622c --- /dev/null +++ b/classpath/java/io/InputStream.java @@ -0,0 +1,27 @@ +package java.io; + +public abstract class InputStream { + public abstract int read() throws IOException; + + public int read(byte[] buffer) throws IOException { + return read(buffer, 0, buffer.length); + } + + public int read(byte[] buffer, int offset, int length) throws IOException { + for (int i = 0; i < length; ++i) { + int c = read(); + if (c == -1) { + if (i == 0) { + return -1; + } else { + return i; + } + } else { + buffer[offset + i] = (byte) (c & 0xFF); + } + } + return length; + } + + public void close() throws IOException { } +} diff --git a/classpath/java/io/OutputStream.java b/classpath/java/io/OutputStream.java new file mode 100644 index 0000000000..40b288944f --- /dev/null +++ b/classpath/java/io/OutputStream.java @@ -0,0 +1,19 @@ +package java.io; + +public abstract class OutputStream { + public abstract void write(int c) throws IOException; + + public void write(byte[] buffer) throws IOException { + write(buffer, 0, buffer.length); + } + + public void write(byte[] buffer, int offset, int length) throws IOException { + for (int i = 0; i < length; ++i) { + write(buffer[offset + i]); + } + } + + public void flush() throws IOException { } + + public void close() throws IOException { } +} diff --git a/classpath/java/io/PrintStream.java b/classpath/java/io/PrintStream.java new file mode 100644 index 0000000000..0524f439b3 --- /dev/null +++ b/classpath/java/io/PrintStream.java @@ -0,0 +1,51 @@ +package java.io; + +public class PrintStream extends OutputStream { + private static final byte[] newline + = System.getProperty("line.separator").getBytes(); + + private final OutputStream out; + private final boolean autoFlush; + + public PrintStream(OutputStream out, boolean autoFlush) { + this.out = out; + this.autoFlush = true; + } + + public PrintStream(OutputStream out) { + this(out, false); + } + + public synchronized void print(String s) { + try { + out.write(s.getBytes()); + if (autoFlush) flush(); + } catch (IOException e) { } + } + + public synchronized void println(String s) { + try { + out.write(s.getBytes()); + out.write(newline); + if (autoFlush) flush(); + } catch (IOException e) { } + } + + public void write(int c) throws IOException { + out.write(c); + if (autoFlush && c == '\n') flush(); + } + + public void write(byte[] buffer, int offset, int length) throws IOException { + out.write(buffer, offset, length); + if (autoFlush) flush(); + } + + public void flush() throws IOException { + out.flush(); + } + + public void close() throws IOException { + out.close(); + } +} diff --git a/classpath/java/lang/String.java b/classpath/java/lang/String.java index c913f27ef9..bac9087698 100644 --- a/classpath/java/lang/String.java +++ b/classpath/java/lang/String.java @@ -130,6 +130,30 @@ public final class String implements Comparable { } } + public byte[] getBytes() { + byte[] b = new byte[length]; + getBytes(0, length, b, 0); + return b; + } + + public void getBytes(int srcOffset, int srcLength, + byte[] dst, int dstOffset) + { + if (srcOffset + srcLength > length) { + throw new IndexOutOfBoundsException(); + } + + if (data instanceof char[]) { + char[] src = (char[]) data; + for (int i = 0; i < srcLength; ++i) { + dst[i + dstOffset] = (byte) src[i + offset + srcOffset]; + } + } else { + byte[] src = (byte[]) data; + System.arraycopy(src, offset + srcOffset, dst, dstOffset, srcLength); + } + } + public void getChars(int srcOffset, int srcLength, char[] dst, int dstOffset) { diff --git a/classpath/java/lang/System.cpp b/classpath/java/lang/System.cpp index 5c96c81a6e..b4f0351d40 100644 --- a/classpath/java/lang/System.cpp +++ b/classpath/java/lang/System.cpp @@ -5,17 +5,6 @@ #undef JNIEXPORT #define JNIEXPORT __attribute__ ((visibility("default"))) -extern "C" JNIEXPORT void JNICALL -Java_java_lang_System_00024Output_print(JNIEnv* e, jobject, jstring s) -{ - jboolean isCopy; - const char* chars = e->GetStringUTFChars(s, &isCopy); - if (chars) { - printf("%s", chars); - } - e->ReleaseStringUTFChars(s, chars); -} - extern "C" JNIEXPORT jstring JNICALL Java_java_lang_System_getProperty(JNIEnv* e, jstring key) { diff --git a/classpath/java/lang/System.java b/classpath/java/lang/System.java index 24ea95b03e..e786e6ac80 100644 --- a/classpath/java/lang/System.java +++ b/classpath/java/lang/System.java @@ -1,13 +1,27 @@ package java.lang; -public abstract class System { - public static final Output out = new Output(); - public static final Output err = out; +import java.io.PrintStream; +import java.io.InputStream; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileDescriptor; +public abstract class System { static { loadLibrary("natives"); } + public static final PrintStream out = new PrintStream + (new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true); + + public static final PrintStream err = new PrintStream + (new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true); + + public static final InputStream in + = new BufferedInputStream(new FileInputStream(FileDescriptor.in)); + public static native void arraycopy(Object src, int srcOffset, Object dst, int dstOffset, int length); @@ -26,13 +40,4 @@ public abstract class System { public static void exit(int code) { Runtime.getRuntime().exit(code); } - - public static class Output { - public synchronized native void print(String s); - - public synchronized void println(String s) { - print(s); - print(getProperty("line.separator")); - } - } } diff --git a/makefile b/makefile index d7b7654b52..fbec232bf5 100644 --- a/makefile +++ b/makefile @@ -16,7 +16,7 @@ src = src classpath = classpath test = test -input = $(cls)/Threads.class +input = $(cls)/Hello.class cxx = g++ cc = gcc diff --git a/src/machine.h b/src/machine.h index 49018fdac5..af0bc1a217 100644 --- a/src/machine.h +++ b/src/machine.h @@ -22,7 +22,7 @@ namespace vm { const bool Verbose = false; -const bool DebugRun = false; +const bool DebugRun = true; const bool DebugStack = false; const bool DebugMonitors = false; diff --git a/test/Reflection.java b/test/Reflection.java index f3878a8609..71a70db815 100644 --- a/test/Reflection.java +++ b/test/Reflection.java @@ -5,7 +5,7 @@ public class Reflection { public static void main(String[] args) throws Exception { Class system = Class.forName("java.lang.System"); Field out = system.getDeclaredField("out"); - Class output = Class.forName("java.lang.System$Output"); + Class output = Class.forName("java.io.PrintStream"); Method println = output.getDeclaredMethod("println", String.class); println.invoke(out.get(null), "Hello, World!");