Merge remote branch 'origin/master' into r0.5

This commit is contained in:
Joel Dice 2011-01-16 19:40:01 -07:00
commit 3fe9171766
12 changed files with 265 additions and 20 deletions

View File

@ -325,10 +325,10 @@ Java_java_io_File_length(JNIEnv* e, jclass, jstring path)
if (chars) { if (chars) {
STRUCT_STAT s; STRUCT_STAT s;
int r = STAT(chars, &s); int r = STAT(chars, &s);
releaseChars(e, path, chars);
if (r == 0) { if (r == 0) {
return s.st_size; return s.st_size;
} }
releaseChars(e, path, chars);
} }
return -1; return -1;
@ -624,7 +624,9 @@ Java_java_io_FileOutputStream_open(JNIEnv* e, jclass, jstring path, jboolean app
{ {
string_t chars = getChars(e, path); string_t chars = getChars(e, path);
if (chars) { if (chars) {
int fd = doOpen(e, chars, append ? (O_WRONLY | O_APPEND) : (O_WRONLY | O_CREAT | O_TRUNC)); int fd = doOpen(e, chars, append
? (O_WRONLY | O_CREAT | O_APPEND)
: (O_WRONLY | O_CREAT | O_TRUNC));
releaseChars(e, path, chars); releaseChars(e, path, chars);
return fd; return fd;
} else { } else {

View File

@ -279,7 +279,7 @@ doListen(JNIEnv* e, int s, sockaddr_in* address)
} }
} }
bool void
doFinishConnect(JNIEnv* e, int socket) doFinishConnect(JNIEnv* e, int socket)
{ {
int error; int error;
@ -289,12 +289,9 @@ doFinishConnect(JNIEnv* e, int socket)
if (r != 0 or size != sizeof(int)) { if (r != 0 or size != sizeof(int)) {
throwIOException(e); throwIOException(e);
} else if (einProgress(error)) { } else if (error and not einProgress(error)) {
return false;
} else if (error != 0) {
throwIOException(e, socketErrorString(e, error)); throwIOException(e, socketErrorString(e, error));
} }
return true;
} }
bool bool
@ -426,12 +423,12 @@ Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e,
return s; return s;
} }
extern "C" JNIEXPORT jboolean JNICALL extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e, Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
jclass, jclass,
jint socket) jint socket)
{ {
return doFinishConnect(e, socket); doFinishConnect(e, socket);
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL

View File

@ -54,7 +54,9 @@ public abstract class ClassLoader {
throw new ClassNotFoundException(); throw new ClassNotFoundException();
} }
protected abstract Class reallyFindLoadedClass(String name); protected Class reallyFindLoadedClass(String name) {
return null;
}
protected final Class findLoadedClass(String name) { protected final Class findLoadedClass(String name) {
return reallyFindLoadedClass(name); return reallyFindLoadedClass(name);

View File

@ -16,6 +16,9 @@ import java.io.OutputStream;
public abstract class URLConnection { public abstract class URLConnection {
protected final URL url; protected final URL url;
protected boolean doInput = true;
protected boolean doOutput = false;
protected boolean useCaches = true;
protected URLConnection(URL url) { protected URLConnection(URL url) {
this.url = url; this.url = url;
@ -29,6 +32,8 @@ public abstract class URLConnection {
return -1; return -1;
} }
public abstract void connect() throws IOException;
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
throw new UnknownServiceException(); throw new UnknownServiceException();
} }
@ -36,4 +41,24 @@ public abstract class URLConnection {
public OutputStream getOutputStream() throws IOException { public OutputStream getOutputStream() throws IOException {
throw new UnknownServiceException(); throw new UnknownServiceException();
} }
public boolean getDoInput() {
return doInput;
}
public boolean getDoOutput() {
return doOutput;
}
public void setDoInput(boolean v) {
doInput = v;
}
public void setDoOutput(boolean v) {
doInput = v;
}
public void setUseCaches(boolean v) {
useCaches = v;
}
} }

View File

@ -24,6 +24,14 @@ public class Channels {
return new MyOutputStream(channel); return new MyOutputStream(channel);
} }
public static ReadableByteChannel newChannel(InputStream stream) {
return new InputStreamChannel(stream);
}
public static WritableByteChannel newChannel(OutputStream stream) {
return new OutputStreamChannel(stream);
}
private static class MyInputStream extends InputStream { private static class MyInputStream extends InputStream {
private final ReadableByteChannel channel; private final ReadableByteChannel channel;
@ -72,4 +80,63 @@ public class Channels {
channel.close(); channel.close();
} }
} }
private static class InputStreamChannel implements ReadableByteChannel {
private InputStream stream;
public InputStreamChannel(InputStream stream) {
this.stream = stream;
}
public void close() throws IOException {
if (stream != null) {
stream.close();
stream = null;
}
}
public boolean isOpen() {
return stream != null;
}
public int read(ByteBuffer b) throws IOException {
int c = stream.read
(b.array(), b.arrayOffset() + b.position(), b.remaining());
if (c > 0) {
b.position(b.position() + c);
}
return c;
}
}
private static class OutputStreamChannel implements WritableByteChannel {
private OutputStream stream;
public OutputStreamChannel(OutputStream stream) {
this.stream = stream;
}
public void close() throws IOException {
if (stream != null) {
stream.close();
stream = null;
}
}
public boolean isOpen() {
return stream != null;
}
public int write(ByteBuffer b) throws IOException {
stream.write(b.array(), b.arrayOffset() + b.position(), b.remaining());
int c = b.remaining();
b.position(b.limit());
return c;
}
}
} }

View File

@ -0,0 +1,20 @@
/* Copyright (c) 2011, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
public interface GatheringByteChannel extends WritableByteChannel {
public long write(ByteBuffer[] srcs) throws IOException;
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
}

View File

@ -19,6 +19,8 @@ public abstract class SelectableChannel implements Channel {
abstract int socketFD(); abstract int socketFD();
abstract void handleReadyOps(int ops);
public abstract SelectableChannel configureBlocking(boolean v) public abstract SelectableChannel configureBlocking(boolean v)
throws IOException; throws IOException;

View File

@ -32,6 +32,10 @@ public class ServerSocketChannel extends SelectableChannel {
return channel.socketFD(); return channel.socketFD();
} }
public void handleReadyOps(int ops) {
channel.handleReadyOps(ops);
}
public SelectableChannel configureBlocking(boolean v) throws IOException { public SelectableChannel configureBlocking(boolean v) throws IOException {
return channel.configureBlocking(v); return channel.configureBlocking(v);
} }

View File

@ -18,12 +18,13 @@ import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class SocketChannel extends SelectableChannel public class SocketChannel extends SelectableChannel
implements ReadableByteChannel, WritableByteChannel implements ReadableByteChannel, GatheringByteChannel
{ {
public static final int InvalidSocket = -1; public static final int InvalidSocket = -1;
int socket = InvalidSocket; int socket = InvalidSocket;
boolean connected = false; boolean connected = false;
boolean readyToConnect = false;
boolean blocking = true; boolean blocking = true;
public static SocketChannel open() throws IOException { public static SocketChannel open() throws IOException {
@ -66,8 +67,23 @@ public class SocketChannel extends SelectableChannel
public boolean finishConnect() throws IOException { public boolean finishConnect() throws IOException {
if (! connected) { if (! connected) {
connected = natFinishConnect(socket); while (! readyToConnect) {
Selector selector = Selector.open();
SelectionKey key = register(selector, SelectionKey.OP_CONNECT, null);
if (blocking) {
selector.select();
} else {
selector.selectNow();
break;
} }
}
natFinishConnect(socket);
connected = readyToConnect;
}
return connected; return connected;
} }
@ -117,6 +133,23 @@ public class SocketChannel extends SelectableChannel
return w; return w;
} }
public long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
long total = 0;
for (int i = offset; i < offset + length; ++i) {
total += write(srcs[i]);
if (srcs[i].hasRemaining()) {
return total;
}
}
return total;
}
private void closeSocket() { private void closeSocket() {
natCloseSocket(socket); natCloseSocket(socket);
} }
@ -125,6 +158,12 @@ public class SocketChannel extends SelectableChannel
return socket; return socket;
} }
void handleReadyOps(int ops) {
if ((ops & SelectionKey.OP_CONNECT) != 0) {
readyToConnect = true;
}
}
public class Handle extends Socket { public class Handle extends Socket {
public void setTcpNoDelay(boolean on) throws SocketException { public void setTcpNoDelay(boolean on) throws SocketException {
natSetTcpNoDelay(socket, on); natSetTcpNoDelay(socket, on);
@ -139,7 +178,7 @@ public class SocketChannel extends SelectableChannel
private static native int natDoConnect(String host, int port, boolean blocking, boolean[] connected) private static native int natDoConnect(String host, int port, boolean blocking, boolean[] connected)
throws IOException; throws IOException;
private static native boolean natFinishConnect(int socket) private static native void natFinishConnect(int socket)
throws IOException; throws IOException;
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking) private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
throws IOException; throws IOException;

View File

@ -96,6 +96,7 @@ class SocketSelector extends Selector {
int ready = natUpdateReadySet(socket, key.interestOps(), state); int ready = natUpdateReadySet(socket, key.interestOps(), state);
key.readyOps(ready); key.readyOps(ready);
if (ready != 0) { if (ready != 0) {
c.handleReadyOps(ready);
selectedKeys.add(key); selectedKeys.add(key);
} }
} }

86
test/DefineClass.java Normal file
View File

@ -0,0 +1,86 @@
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
public class DefineClass {
private static File findClass(String name, File directory) {
File[] files = directory.listFiles();
for (File file: directory.listFiles()) {
if (file.isFile()) {
if (file.getName().equals(name + ".class")) {
return file;
}
} else if (file.isDirectory()) {
File result = findClass(name, file);
if (result != null) {
return result;
}
}
}
return null;
}
private static byte[] read(File file) throws IOException {
byte[] bytes = new byte[(int) file.length()];
FileInputStream in = new FileInputStream(file);
try {
if (in.read(bytes) != (int) file.length()) {
throw new RuntimeException();
}
return bytes;
} finally {
in.close();
}
}
private static Class loadClass(String name) throws Exception {
return new MyClassLoader(DefineClass.class.getClassLoader()).defineClass
(name, read(findClass(name, new File(System.getProperty("user.dir")))));
}
private static void testStatic() throws Exception {
loadClass("DefineClass$Hello")
.getMethod("main", String[].class).invoke(null, (Object) new String[0]);
}
private static void testDerived() throws Exception {
System.out.println
(String.valueOf
(((Base) loadClass("DefineClass$Derived").newInstance()).zip()));
}
public static void main(String[] args) throws Exception {
testStatic();
testDerived();
}
private static class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent) {
super(parent);
}
public Class defineClass(String name, byte[] bytes) {
return super.defineClass(name, bytes, 0, bytes.length);
}
}
public static class Hello {
public static void main(String[] args) {
System.out.println("hello, world!");
}
}
public abstract static class Base {
public int foo;
public void bar() { }
public abstract int zip();
}
public static class Derived extends Base {
public int zip() {
return 42;
}
}
}

View File

@ -4,14 +4,9 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
public class FileOutput { public class FileOutput {
private static void test(boolean appendFirst) throws IOException {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
try { try {
FileOutputStream f = new FileOutputStream("test.txt"); FileOutputStream f = new FileOutputStream("test.txt", appendFirst);
f.write("Hello world!\n".getBytes()); f.write("Hello world!\n".getBytes());
f.close(); f.close();
@ -37,4 +32,9 @@ public class FileOutput {
} }
} }
public static void main(String[] args) throws IOException {
test(false);
test(true);
}
} }