mirror of
https://github.com/corda/corda.git
synced 2025-06-21 00:23:09 +00:00
Merge remote-tracking branch 'rt/master'
This commit is contained in:
@ -423,6 +423,27 @@ public class Classes {
|
||||
}
|
||||
}
|
||||
|
||||
public static VMMethod findMethod(ClassLoader loader,
|
||||
String class_,
|
||||
String name,
|
||||
String spec)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
VMClass c = SystemClassLoader.vmClass(loader.loadClass(class_));
|
||||
VMMethod[] methodTable = c.methodTable;
|
||||
if (methodTable != null) {
|
||||
link(c);
|
||||
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
VMMethod m = methodTable[i];
|
||||
if (toString(m.name).equals(name) && toString(m.spec).equals(spec)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int findMethod(VMClass vmClass, String name,
|
||||
Class[] parameterTypes)
|
||||
{
|
||||
|
@ -20,6 +20,8 @@ import java.util.Enumeration;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class SystemClassLoader extends ClassLoader {
|
||||
public static native ClassLoader appLoader();
|
||||
|
||||
private native VMClass findVMClass(String name)
|
||||
throws ClassNotFoundException;
|
||||
|
||||
@ -81,6 +83,8 @@ public class SystemClassLoader extends ClassLoader {
|
||||
if (source != null) {
|
||||
// todo: load attributes from JAR manifest
|
||||
definePackage(name, null, null, null, null, null, null, null);
|
||||
} else {
|
||||
definePackage(name, null, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,17 +10,111 @@
|
||||
|
||||
package avian.http;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.URLConnection;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Handler extends URLStreamHandler {
|
||||
protected URLConnection openConnection(URL url) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public class Handler extends URLStreamHandler
|
||||
{
|
||||
public URLConnection openConnection(URL url) throws IOException
|
||||
{
|
||||
return new HttpURLConnection(url);
|
||||
}
|
||||
|
||||
class HttpURLConnection extends URLConnection
|
||||
{
|
||||
Socket socket;
|
||||
private BufferedWriter writer;
|
||||
private InputStream bin;
|
||||
private Map<String,String> header = new HashMap<String, String>();
|
||||
private int status;
|
||||
|
||||
protected HttpURLConnection(URL url)
|
||||
{
|
||||
super(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect() throws IOException
|
||||
{
|
||||
if(socket == null)
|
||||
{
|
||||
URLConnection con = null;
|
||||
String host = url.getHost();
|
||||
int port =url.getPort();
|
||||
if(port < 0) port = 80;
|
||||
socket = new Socket(host, port);
|
||||
OutputStream out = socket.getOutputStream();
|
||||
writer = new BufferedWriter(new OutputStreamWriter(out));
|
||||
writer.write("GET " + url.getPath() + " HTTP/1.1");
|
||||
writer.write("\r\nHost: " + host);
|
||||
writer.write("\r\n\r\n");
|
||||
writer.flush();
|
||||
bin = new BufferedInputStream(socket.getInputStream());
|
||||
readHeader();
|
||||
// System.out.println("Status: " + status);
|
||||
// System.out.println("Headers: " + header);
|
||||
}
|
||||
}
|
||||
|
||||
private void readHeader() throws IOException
|
||||
{
|
||||
byte[] buf = new byte[8192];
|
||||
int b = 0;
|
||||
int index = 0;
|
||||
while(b >= 0)
|
||||
{
|
||||
if(index >= 4 && buf[index-4] == '\r' && buf[index-3] == '\n' && buf[index-2] == '\r' && buf[index-1] == '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
b = bin.read();
|
||||
buf[index] = (byte) b;
|
||||
index++;
|
||||
if(index >= buf.length)
|
||||
{
|
||||
throw new IOException("Header exceeded maximum size of 8k.");
|
||||
}
|
||||
}
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, index)));
|
||||
String line = reader.readLine();
|
||||
int x = line.indexOf(' ');
|
||||
status = Integer.parseInt(line.substring(x + 1 , line.indexOf(' ', x+1)));
|
||||
while(line != null)
|
||||
{
|
||||
int i = line.indexOf(':');
|
||||
if(i > 0)
|
||||
{
|
||||
header.put(line.substring(0, i), line.substring(i + 1) .trim());
|
||||
}
|
||||
line = reader.readLine();
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
connect();
|
||||
return bin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException("Can' write to HTTP Connection");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,11 @@
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class BufferedInputStream extends InputStream {
|
||||
private final InputStream in;
|
||||
private final byte[] buffer;
|
||||
@ -25,17 +27,16 @@ public class BufferedInputStream extends InputStream {
|
||||
this(in, 4096);
|
||||
}
|
||||
|
||||
private void fill() throws IOException {
|
||||
private int fill() throws IOException {
|
||||
position = 0;
|
||||
limit = in.read(buffer);
|
||||
|
||||
return limit;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (position >= limit) {
|
||||
fill();
|
||||
if (limit == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (position >= limit && fill() == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return buffer[position++] & 0xFF;
|
||||
@ -43,7 +44,9 @@ public class BufferedInputStream extends InputStream {
|
||||
|
||||
public int read(byte[] b, int offset, int length) throws IOException {
|
||||
int count = 0;
|
||||
|
||||
if (position >= limit && fill() == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (position < limit) {
|
||||
int remaining = limit - position;
|
||||
if (remaining > length) {
|
||||
@ -57,8 +60,8 @@ public class BufferedInputStream extends InputStream {
|
||||
offset += remaining;
|
||||
length -= remaining;
|
||||
}
|
||||
|
||||
while (length > 0) {
|
||||
while (length > 0 && in.available() > 0)
|
||||
{
|
||||
int c = in.read(b, offset, length);
|
||||
if (c == -1) {
|
||||
if (count == 0) {
|
||||
@ -69,13 +72,8 @@ public class BufferedInputStream extends InputStream {
|
||||
offset += c;
|
||||
count += c;
|
||||
length -= c;
|
||||
|
||||
if (in.available() <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -87,3 +85,4 @@ public class BufferedInputStream extends InputStream {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,10 @@ import java.util.Random;
|
||||
public final class Math {
|
||||
public static final double E = 2.718281828459045;
|
||||
public static final double PI = 3.141592653589793;
|
||||
private static final Random random = new Random();
|
||||
|
||||
private static class Static {
|
||||
public static final Random random = new Random();
|
||||
}
|
||||
|
||||
private Math() { }
|
||||
|
||||
@ -84,7 +87,7 @@ public final class Math {
|
||||
}
|
||||
|
||||
public static double random() {
|
||||
return random.nextDouble();
|
||||
return Static.random.nextDouble();
|
||||
}
|
||||
|
||||
public static native double floor(double v);
|
||||
|
@ -22,7 +22,9 @@ import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
|
||||
public abstract class System {
|
||||
private static final long NanoTimeBaseInMillis = currentTimeMillis();
|
||||
private static class NanoTime {
|
||||
public static final long BaseInMillis = currentTimeMillis();
|
||||
}
|
||||
|
||||
private static class Static {
|
||||
public static Properties properties = makeProperties();
|
||||
@ -94,7 +96,7 @@ public abstract class System {
|
||||
public static native int identityHashCode(Object o);
|
||||
|
||||
public static long nanoTime() {
|
||||
return (currentTimeMillis() - NanoTimeBaseInMillis) * 1000000;
|
||||
return (currentTimeMillis() - NanoTime.BaseInMillis) * 1000000;
|
||||
}
|
||||
|
||||
public static String mapLibraryName(String name) {
|
||||
|
@ -187,14 +187,28 @@ public class LambdaMetafactory {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static CallSite metafactory(MethodHandles.Lookup caller,
|
||||
String invokedName,
|
||||
MethodType invokedType,
|
||||
MethodType methodType,
|
||||
MethodHandle methodImplementation,
|
||||
MethodType instantiatedMethodType)
|
||||
throws LambdaConversionException
|
||||
|
||||
public static byte[] makeLambda(String invokedName,
|
||||
String invokedType,
|
||||
String methodType,
|
||||
String implementationClass,
|
||||
String implementationName,
|
||||
String implementationSpec,
|
||||
int implementationKind)
|
||||
{
|
||||
return makeLambda(invokedName,
|
||||
new MethodType(invokedType),
|
||||
new MethodType(methodType),
|
||||
new MethodHandle(implementationClass,
|
||||
implementationName,
|
||||
implementationSpec,
|
||||
implementationKind));
|
||||
}
|
||||
|
||||
private static byte[] makeLambda(String invokedName,
|
||||
MethodType invokedType,
|
||||
MethodType methodType,
|
||||
MethodHandle methodImplementation)
|
||||
{
|
||||
String className;
|
||||
{ int number;
|
||||
@ -265,8 +279,19 @@ public class LambdaMetafactory {
|
||||
throw error;
|
||||
}
|
||||
|
||||
byte[] classData = out.toByteArray();
|
||||
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static CallSite metafactory(MethodHandles.Lookup caller,
|
||||
String invokedName,
|
||||
MethodType invokedType,
|
||||
MethodType methodType,
|
||||
MethodHandle methodImplementation,
|
||||
MethodType instantiatedMethodType)
|
||||
throws LambdaConversionException
|
||||
{
|
||||
byte[] classData = makeLambda(invokedName, invokedType, methodType, methodImplementation);
|
||||
|
||||
try {
|
||||
return new CallSite
|
||||
(new MethodHandle
|
||||
|
@ -1,6 +1,7 @@
|
||||
package java.lang.invoke;
|
||||
|
||||
import avian.Classes;
|
||||
import avian.SystemClassLoader;
|
||||
|
||||
public class MethodHandle {
|
||||
static final int REF_invokeStatic = 6;
|
||||
@ -17,6 +18,20 @@ public class MethodHandle {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
MethodHandle(String class_,
|
||||
String name,
|
||||
String spec,
|
||||
int kind)
|
||||
{
|
||||
this.kind = kind;
|
||||
this.loader = SystemClassLoader.appLoader();
|
||||
try {
|
||||
this.method = Classes.findMethod(this.loader, class_, name, spec);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (method.class_ != null) {
|
||||
|
@ -4,6 +4,7 @@ import static avian.Assembler.*;
|
||||
|
||||
import avian.Assembler;
|
||||
import avian.Classes;
|
||||
import avian.SystemClassLoader;
|
||||
import avian.VMClass;
|
||||
|
||||
import java.util.List;
|
||||
@ -25,6 +26,12 @@ public final class MethodType implements java.io.Serializable {
|
||||
this.spec = spec;
|
||||
}
|
||||
|
||||
MethodType(String spec) {
|
||||
this.loader = SystemClassLoader.appLoader();
|
||||
this.spec = new byte[spec.length() + 1];
|
||||
spec.getBytes(0, spec.length(), this.spec, 0);
|
||||
}
|
||||
|
||||
public String toMethodDescriptorString() {
|
||||
return Classes.makeString(spec, 0, spec.length - 1);
|
||||
}
|
||||
|
@ -86,18 +86,16 @@ public class Socket implements Closeable, AutoCloseable {
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
if(buffer.length == 0) return 0; //spec says return 0 if buffer length is zero.
|
||||
int fullSize = buffer.length;
|
||||
int index = 0;
|
||||
int size;
|
||||
do {
|
||||
size = recv(sock, buffer, index, Math.min(fullSize, Socket.BUFFER_SIZE));
|
||||
fullSize -= size;
|
||||
index += size;
|
||||
} while (fullSize != 0 && size != 0);
|
||||
return index;
|
||||
size = recv(sock, buffer, 0, Math.min(fullSize, Socket.BUFFER_SIZE));
|
||||
fullSize -= size;
|
||||
//removed loop, because otherwise interactive protocols will not work.
|
||||
if(size < 0) throw new IOException("Error while reading stream"); //as the manpage of recv says, a value below zero indicates an error.
|
||||
if(size == 0) return -1; // if the stream is closed (size == 0), then return -1 to indicate end of stream.
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private class SocketOutputStream extends OutputStream {
|
||||
|
Reference in New Issue
Block a user