Merge branch 'master' of github.com:ReadyTalk/avian

This commit is contained in:
Joshua Warner
2012-10-30 14:00:16 -06:00
75 changed files with 3202 additions and 767 deletions

View File

@ -72,12 +72,16 @@ public class File implements Serializable {
}
}
private static String normalize(String path) {
if ("\\".equals(FileSeparator)) {
return path.replace('/', '\\');
} else {
return path;
private static String stripSeparators(String p) {
while (p.endsWith(FileSeparator)) {
p = p.substring(0, p.length() - 1);
}
return p;
}
private static String normalize(String path) {
return stripSeparators
("\\".equals(FileSeparator) ? path.replace('/', '\\') : path);
}
public static native boolean rename(String old, String new_);
@ -150,7 +154,7 @@ public class File implements Serializable {
public String getParent() {
int index = path.lastIndexOf(FileSeparator);
if (index >= 0) {
return path.substring(0, index);
return normalize(path.substring(0, index));
} else {
return null;
}
@ -239,11 +243,15 @@ public class File implements Serializable {
public File[] listFiles(FilenameFilter filter) {
String[] list = list(filter);
File[] result = new File[list.length];
for (int i = 0; i < list.length; ++i) {
result[i] = new File(this, list[i]);
if (list != null) {
File[] result = new File[list.length];
for (int i = 0; i < list.length; ++i) {
result[i] = new File(this, list[i]);
}
return result;
} else {
return null;
}
return result;
}
public String[] list() {
@ -254,22 +262,26 @@ public class File implements Serializable {
long handle = 0;
try {
handle = openDir(path);
Pair list = null;
int count = 0;
for (String s = readDir(handle); s != null; s = readDir(handle)) {
if (filter == null || filter.accept(this, s)) {
list = new Pair(s, list);
++ count;
if (handle != 0) {
Pair list = null;
int count = 0;
for (String s = readDir(handle); s != null; s = readDir(handle)) {
if (filter == null || filter.accept(this, s)) {
list = new Pair(s, list);
++ count;
}
}
}
String[] result = new String[count];
for (int i = count - 1; i >= 0; --i) {
result[i] = list.value;
list = list.next;
}
String[] result = new String[count];
for (int i = count - 1; i >= 0; --i) {
result[i] = list.value;
list = list.next;
}
return result;
return result;
} else {
return null;
}
} finally {
if (handle != 0) {
closeDir(handle);

View File

@ -13,6 +13,8 @@ package java.io;
import avian.Utf8;
public class InputStreamReader extends Reader {
private static final int MultibytePadding = 4;
private final InputStream in;
public InputStreamReader(InputStream in) {
@ -28,19 +30,60 @@ public class InputStreamReader extends Reader {
throw new UnsupportedEncodingException(encoding);
}
}
public int read(char[] b, int offset, int length) throws IOException {
byte[] buffer = new byte[length];
int c = in.read(buffer);
if (length == 0) {
return 0;
}
if (c <= 0) return c;
byte[] buffer = new byte[length + MultibytePadding];
int bufferLength = length;
int bufferOffset = 0;
while (true) {
int c = in.read(buffer, bufferOffset, bufferLength);
char[] buffer16 = Utf8.decode16(buffer, 0, c);
if (c <= 0) {
if (bufferOffset > 0) {
// if we've reached the end of the stream while trying to
// read a multibyte character, we still need to return any
// competely-decoded characters, plus \ufffd to indicate an
// unknown character
c = 1;
while (bufferOffset > 0) {
char[] buffer16 = Utf8.decode16(buffer, 0, bufferOffset);
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
if (buffer16 != null) {
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
c = buffer16.length + 1;
break;
} else {
-- bufferOffset;
}
}
return buffer16.length;
b[offset + c - 1] = '\ufffd';
}
return c;
}
bufferOffset += c;
char[] buffer16 = Utf8.decode16(buffer, 0, bufferOffset);
if (buffer16 != null) {
bufferOffset = 0;
System.arraycopy(buffer16, 0, b, offset, buffer16.length);
return buffer16.length;
} else {
// the buffer ended in an incomplete multibyte character, so
// we try to read a another byte at a time until it's complete
bufferLength = 1;
}
}
}
public void close() throws IOException {

View File

@ -0,0 +1,17 @@
/* Copyright (c) 2012, 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.lang;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated { }

View File

@ -14,6 +14,10 @@ public final class Float extends Number {
public static final Class TYPE = Class.forCanonicalName("F");
private static final int EXP_BIT_MASK = 0x7F800000;
private static final int SIGNIF_BIT_MASK = 0x007FFFFF;
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
public static final float NaN = 0.0f / 0.0f;
private final float value;

View File

@ -156,6 +156,10 @@ public class Thread implements Runnable {
}
public static void sleep(long milliseconds) throws InterruptedException {
if (milliseconds <= 0) {
milliseconds = 1;
}
Thread t = currentThread();
if (t.sleepLock == null) {
t.sleepLock = new Object();

View File

@ -0,0 +1,19 @@
/* Copyright (c) 2012, 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.net;
import java.io.IOException;
public abstract class DatagramSocket {
public abstract SocketAddress getRemoteSocketAddress();
public abstract void bind(SocketAddress address) throws SocketException;
}

View File

@ -0,0 +1,13 @@
/* Copyright (c) 2012, 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.net;
public interface ProtocolFamily { }

View File

@ -0,0 +1,15 @@
/* Copyright (c) 2012, 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.net;
public enum StandardProtocolFamily implements ProtocolFamily {
INET;
}

View File

@ -83,8 +83,8 @@ public final class URL {
{
if ("http".equals(protocol) || "https".equals(protocol)) {
return new avian.http.Handler();
} else if ("resource".equals(protocol)) {
return new avian.resource.Handler();
} else if ("avianvmresource".equals(protocol)) {
return new avian.avianvmresource.Handler();
} else if ("file".equals(protocol)) {
return new avian.file.Handler();
} else if ("jar".equals(protocol)) {

View File

@ -0,0 +1,92 @@
/* Copyright (c) 2008-2012, 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;
class ArrayByteBuffer extends ByteBuffer {
private final byte[] array;
private final int arrayOffset;
ArrayByteBuffer(byte[] array, int offset, int length, boolean readOnly) {
super(readOnly);
this.array = array;
this.arrayOffset = offset;
this.capacity = length;
this.limit = length;
this.position = 0;
}
public ByteBuffer asReadOnlyBuffer() {
ByteBuffer b = new ArrayByteBuffer(array, arrayOffset, capacity, true);
b.position(position());
b.limit(limit());
return b;
}
public boolean hasArray() {
return true;
}
public byte[] array() {
return array;
}
public ByteBuffer slice() {
return new ArrayByteBuffer
(array, arrayOffset + position, remaining(), true);
}
public int arrayOffset() {
return arrayOffset;
}
protected void doPut(int position, byte val) {
array[arrayOffset + position] = val;
}
public ByteBuffer put(ByteBuffer src) {
int length = src.remaining();
checkPut(position, length);
src.get(array, arrayOffset + position, length);
position += length;
return this;
}
public ByteBuffer put(byte[] src, int offset, int length) {
checkPut(position, length);
System.arraycopy(src, offset, array, arrayOffset + position, length);
position += length;
return this;
}
public ByteBuffer get(byte[] dst, int offset, int length) {
checkGet(position, length);
System.arraycopy(array, arrayOffset + position, dst, offset, length);
position += length;
return this;
}
protected byte doGet(int position) {
return array[arrayOffset+position];
}
public String toString() {
return "(ArrayByteBuffer with array: " + array
+ " arrayOffset: " + arrayOffset
+ " position: " + position
+ " limit: " + limit
+ " capacity: " + capacity + ")";
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008-2011, Avian Contributors
/* Copyright (c) 2008-2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
@ -10,13 +10,22 @@
package java.nio;
public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
private final byte[] array;
private int arrayOffset;
public abstract class ByteBuffer
extends Buffer
implements Comparable<ByteBuffer>
{
private final boolean readOnly;
protected ByteBuffer(boolean readOnly) {
this.readOnly = readOnly;
}
public static ByteBuffer allocate(int capacity) {
return new ByteBuffer(new byte[capacity], 0, capacity, false);
return new ArrayByteBuffer(new byte[capacity], 0, capacity, false);
}
public static ByteBuffer allocateDirect(int capacity) {
return FixedArrayByteBuffer.make(capacity);
}
public static ByteBuffer wrap(byte[] array) {
@ -24,23 +33,53 @@ public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
}
public static ByteBuffer wrap(byte[] array, int offset, int length) {
return new ByteBuffer(array, offset, length, false);
return new ArrayByteBuffer(array, offset, length, false);
}
private ByteBuffer(byte[] array, int offset, int length, boolean readOnly) {
this.array = array;
this.readOnly = readOnly;
arrayOffset = offset;
capacity = length;
limit = capacity;
position = 0;
public abstract ByteBuffer asReadOnlyBuffer();
public abstract ByteBuffer slice();
protected abstract void doPut(int offset, byte val);
public abstract ByteBuffer put(byte[] arr, int offset, int len);
protected abstract byte doGet(int offset);
public abstract ByteBuffer get(byte[] dst, int offset, int length);
public boolean hasArray() {
return false;
}
public ByteBuffer asReadOnlyBuffer() {
ByteBuffer b = new ByteBuffer(array, arrayOffset, capacity, true);
b.position(position());
b.limit(limit());
return b;
public ByteBuffer compact() {
int remaining = remaining();
if (position != 0) {
ByteBuffer b = slice();
position = 0;
put(b);
}
position = remaining;
limit(capacity());
return this;
}
public ByteBuffer put(ByteBuffer src) {
if (src.hasArray()) {
checkPut(position, src.remaining());
put(src.array(), src.arrayOffset() + src.position, src.remaining());
src.position(src.position() + src.remaining());
return this;
} else {
byte[] buffer = new byte[src.remaining()];
src.get(buffer);
return put(buffer);
}
}
public int compareTo(ByteBuffer o) {
@ -60,37 +99,22 @@ public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
}
public byte[] array() {
return array;
}
public ByteBuffer slice() {
return new ByteBuffer(array, arrayOffset + position, remaining(), true);
throw new UnsupportedOperationException();
}
public int arrayOffset() {
return arrayOffset;
throw new UnsupportedOperationException();
}
public ByteBuffer compact() {
if (position != 0) {
System.arraycopy(array, arrayOffset+position, array, arrayOffset, remaining());
}
position=remaining();
limit(capacity());
public ByteBuffer put(int offset, byte val) {
checkPut(offset, 1);
doPut(offset, val);
return this;
}
public ByteBuffer put(byte val) {
checkPut(1);
array[arrayOffset+(position++)] = val;
return this;
}
public ByteBuffer put(ByteBuffer src) {
checkPut(src.remaining());
put(src.array, src.arrayOffset + src.position, src.remaining());
src.position += src.remaining();
put(position, val);
++ position;
return this;
}
@ -98,125 +122,126 @@ public class ByteBuffer extends Buffer implements Comparable<ByteBuffer> {
return put(arr, 0, arr.length);
}
public ByteBuffer put(byte[] arr, int offset, int len) {
checkPut(len);
System.arraycopy(arr, offset, array, arrayOffset+position, len);
position += len;
public ByteBuffer putLong(int position, long val) {
checkPut(position, 8);
doPut(position , (byte) ((val >> 56) & 0xff));
doPut(position + 1, (byte) ((val >> 48) & 0xff));
doPut(position + 2, (byte) ((val >> 40) & 0xff));
doPut(position + 3, (byte) ((val >> 32) & 0xff));
doPut(position + 4, (byte) ((val >> 24) & 0xff));
doPut(position + 5, (byte) ((val >> 16) & 0xff));
doPut(position + 6, (byte) ((val >> 8) & 0xff));
doPut(position + 7, (byte) ((val ) & 0xff));
return this;
}
public ByteBuffer putInt(int position, int val) {
checkPut(position, 4);
array[arrayOffset+position] = (byte)((val >> 24) & 0xff);
array[arrayOffset+position+1] = (byte)((val >> 16) & 0xff);
array[arrayOffset+position+2] = (byte)((val >> 8) & 0xff);
array[arrayOffset+position+3] = (byte)((val ) & 0xff);
doPut(position , (byte) ((val >> 24) & 0xff));
doPut(position + 1, (byte) ((val >> 16) & 0xff));
doPut(position + 2, (byte) ((val >> 8) & 0xff));
doPut(position + 3, (byte) ((val ) & 0xff));
return this;
}
public ByteBuffer putShort(int position, short val) {
checkPut(position, 2);
doPut(position , (byte) ((val >> 8) & 0xff));
doPut(position + 1, (byte) ((val ) & 0xff));
return this;
}
public ByteBuffer putLong(long val) {
putLong(position, val);
position += 8;
return this;
}
public ByteBuffer putInt(int val) {
checkPut(4);
putInt(position, val);
position += 4;
return this;
}
public ByteBuffer putShort(short val) {
checkPut(2);
put((byte)((val >> 8) & 0xff));
put((byte)(val & 0xff));
return this;
}
public ByteBuffer putLong(long val) {
checkPut(8);
putInt((int)(val >> 32));
putInt((int)val);
putShort(position, val);
position += 2;
return this;
}
public byte get() {
checkGet(1);
return array[arrayOffset+(position++)];
return get(position++);
}
public byte get(int position) {
checkGet(position, 1);
return doGet(position);
}
public ByteBuffer get(byte[] dst) {
return get(dst, 0, dst.length);
}
public ByteBuffer get(byte[] dst, int offset, int length) {
checkGet(length);
System.arraycopy(array, arrayOffset + position, dst, offset, length);
position += length;
return this;
}
public long getLong(int position) {
checkGet(position, 8);
public byte get(int position) {
checkGet(position, 1);
return array[arrayOffset+position];
return (((long) (doGet(position ) & 0xFF)) << 56)
| (((long) (doGet(position + 1) & 0xFF)) << 48)
| (((long) (doGet(position + 2) & 0xFF)) << 40)
| (((long) (doGet(position + 3) & 0xFF)) << 32)
| (((long) (doGet(position + 4) & 0xFF)) << 24)
| (((long) (doGet(position + 5) & 0xFF)) << 16)
| (((long) (doGet(position + 6) & 0xFF)) << 8)
| (((long) (doGet(position + 7) & 0xFF)) );
}
public int getInt(int position) {
checkGet(position, 4);
int p = arrayOffset + position;
return ((array[p] & 0xFF) << 24)
| ((array[p + 1] & 0xFF) << 16)
| ((array[p + 2] & 0xFF) << 8)
| ((array[p + 3] & 0xFF));
return (((int) (doGet(position ) & 0xFF)) << 24)
| (((int) (doGet(position + 1) & 0xFF)) << 16)
| (((int) (doGet(position + 2) & 0xFF)) << 8)
| (((int) (doGet(position + 3) & 0xFF)) );
}
public short getShort(int position) {
checkGet(position, 2);
int p = arrayOffset + position;
return (short) (((array[p] & 0xFF) << 8) | ((array[p + 1] & 0xFF)));
}
public int getInt() {
checkGet(4);
int i = get() << 24;
i |= (get() & 0xff) << 16;
i |= (get() & 0xff) << 8;
i |= (get() & 0xff);
return i;
}
public short getShort() {
checkGet(2);
short s = (short)(get() << 8);
s |= get() & 0xff;
return s;
return (short) (( ((int) (doGet(position ) & 0xFF)) << 8)
| (((int) (doGet(position + 1) & 0xFF)) ));
}
public long getLong() {
checkGet(8);
long l = (long)getInt() << 32;
l |= (long)getInt() & 0xffffffffL;
return l;
long r = getLong(position);
position += 8;
return r;
}
private void checkPut(int amount) {
if (readOnly) throw new ReadOnlyBufferException();
if (amount > limit-position) throw new IndexOutOfBoundsException();
public int getInt() {
int r = getInt(position);
position += 4;
return r;
}
private void checkPut(int position, int amount) {
public short getShort() {
short r = getShort(position);
position += 2;
return r;
}
protected void checkPut(int position, int amount) {
if (readOnly) throw new ReadOnlyBufferException();
if (position < 0 || position+amount > limit)
throw new IndexOutOfBoundsException();
}
private void checkGet(int amount) {
protected void checkGet(int position, int amount) {
if (amount > limit-position) throw new IndexOutOfBoundsException();
}
private void checkGet(int position, int amount) {
if (position < 0 || position+amount > limit)
throw new IndexOutOfBoundsException();
}
public String toString() {
return "(ByteBuffer with array: " + array + " arrayOffset: " + arrayOffset + " position: " + position + " remaining; " + remaining() + ")";
}
}

View File

@ -0,0 +1,105 @@
/* Copyright (c) 2008-2012, 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;
import sun.misc.Unsafe;
class DirectByteBuffer extends ByteBuffer {
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final int baseOffset = unsafe.arrayBaseOffset(byte[].class);
protected final long address;
protected DirectByteBuffer(long address, int capacity, boolean readOnly) {
super(readOnly);
this.address = address;
this.capacity = capacity;
this.limit = capacity;
this.position = 0;
}
protected DirectByteBuffer(long address, int capacity) {
this(address, capacity, false);
}
public ByteBuffer asReadOnlyBuffer() {
ByteBuffer b = new DirectByteBuffer(address, capacity, true);
b.position(position());
b.limit(limit());
return b;
}
public ByteBuffer slice() {
return new DirectByteBuffer(address + position, remaining(), true);
}
protected void doPut(int position, byte val) {
unsafe.putByte(address + position, val);
}
public ByteBuffer put(ByteBuffer src) {
if (src instanceof DirectByteBuffer) {
checkPut(position, src.remaining());
DirectByteBuffer b = (DirectByteBuffer) src;
unsafe.copyMemory
(b.address + b.position, address + position, b.remaining());
position += b.remaining();
b.position += b.remaining();
return this;
} else {
return super.put(src);
}
}
public ByteBuffer put(byte[] src, int offset, int length) {
if (offset < 0 || offset + length > src.length) {
throw new ArrayIndexOutOfBoundsException();
}
checkPut(position, length);
unsafe.copyMemory
(src, baseOffset + offset, null, address + position, length);
position += length;
return this;
}
public ByteBuffer get(byte[] dst, int offset, int length) {
if (offset < 0 || offset + length > dst.length) {
throw new ArrayIndexOutOfBoundsException();
}
checkGet(position, length);
unsafe.copyMemory
(null, address + position, dst, baseOffset + offset, length);
return this;
}
protected byte doGet(int position) {
return unsafe.getByte(address + position);
}
public String toString() {
return "(DirectByteBuffer with address: " + address
+ " position: " + position
+ " limit: " + limit
+ " capacity: " + capacity + ")";
}
}

View File

@ -0,0 +1,58 @@
/* Copyright (c) 2008-2012, 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;
class FixedArrayByteBuffer extends DirectByteBuffer {
private final byte[] array;
private final int arrayOffset;
private FixedArrayByteBuffer(long address,
byte[] array,
int offset,
int capacity,
boolean readOnly)
{
super(address, capacity, readOnly);
this.array = array;
this.arrayOffset = offset;
}
public static FixedArrayByteBuffer make(int capacity) {
long[] address = new long[1];
byte[] array = allocateFixed(capacity, address);
return new FixedArrayByteBuffer(address[0], array, 0, capacity, false);
}
private static native byte[] allocateFixed(int capacity, long[] address);
public ByteBuffer asReadOnlyBuffer() {
ByteBuffer b = new FixedArrayByteBuffer
(address, array, arrayOffset, capacity, true);
b.position(position());
b.limit(limit());
return b;
}
public ByteBuffer slice() {
return new FixedArrayByteBuffer
(address + position, array, arrayOffset + position, remaining(), true);
}
public String toString() {
return "(FixedArrayByteBuffer with address: " + address
+ " array: " + array
+ " arrayOffset: " + arrayOffset
+ " position: " + position
+ " limit: " + limit
+ " capacity: " + capacity + ")";
}
}

View File

@ -0,0 +1,180 @@
/* Copyright (c) 2012, 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;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.net.ProtocolFamily;
import java.net.Socket;
import java.net.SocketException;
import java.net.DatagramSocket;
import java.net.StandardProtocolFamily;
public class DatagramChannel extends SelectableChannel
implements ReadableByteChannel, WritableByteChannel
{
public static final int InvalidSocket = -1;
private int socket = InvalidSocket;
private boolean blocking = true;
public SelectableChannel configureBlocking(boolean v) throws IOException {
blocking = v;
if (socket != InvalidSocket) {
configureBlocking(socket, v);
}
return this;
}
int socketFD() {
return socket;
}
void handleReadyOps(int ops) {
// ignore
}
public static DatagramChannel open(ProtocolFamily family)
throws IOException
{
if (family.equals(StandardProtocolFamily.INET)) {
Socket.init();
return new DatagramChannel();
} else {
throw new UnsupportedOperationException();
}
}
public static DatagramChannel open()
throws IOException
{
return open(StandardProtocolFamily.INET);
}
public DatagramSocket socket() {
return new Handle();
}
public DatagramChannel bind(SocketAddress address) throws IOException {
InetSocketAddress inetAddress;
try {
inetAddress = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new UnsupportedAddressTypeException();
}
socket = bind(inetAddress.getHostName(), inetAddress.getPort());
return this;
}
public DatagramChannel connect(SocketAddress address) throws IOException {
InetSocketAddress inetAddress;
try {
inetAddress = (InetSocketAddress) address;
} catch (ClassCastException e) {
throw new UnsupportedAddressTypeException();
}
socket = connect(inetAddress.getHostName(), inetAddress.getPort());
return this;
}
public int write(ByteBuffer b) throws IOException {
if (b.remaining() == 0) return 0;
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int c = write
(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
if (c > 0) {
b.position(b.position() + c);
}
return c;
}
public int read(ByteBuffer b) throws IOException {
int p = b.position();
receive(b);
return b.position() - p;
}
public SocketAddress receive(ByteBuffer b) throws IOException {
if (b.remaining() == 0) return null;
byte[] array = b.array();
if (array == null) throw new NullPointerException();
int[] address = new int[2];
int c = receive
(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking,
address);
if (c > 0) {
b.position(b.position() + c);
return new InetSocketAddress(ipv4ToString(address[0]), address[1]);
} else {
return null;
}
}
private static String ipv4ToString(int address) {
StringBuilder sb = new StringBuilder();
sb.append( address >> 24 ).append('.')
.append((address >> 16) & 0xFF).append('.')
.append((address >> 8) & 0xFF).append('.')
.append( address & 0xFF);
return sb.toString();
}
public class Handle extends DatagramSocket {
public SocketAddress getRemoteSocketAddress() {
throw new UnsupportedOperationException();
}
public void bind(SocketAddress address) throws SocketException {
try {
DatagramChannel.this.bind(address);
} catch (SocketException e) {
throw e;
} catch (IOException e) {
SocketException se = new SocketException();
se.initCause(e);
throw se;
}
}
}
private static native void configureBlocking(int socket, boolean blocking)
throws IOException;
private static native int bind(String hostname, int port)
throws IOException;
private static native int connect(String hostname, int port)
throws IOException;
private static native int write(int socket, byte[] array, int offset,
int length, boolean blocking)
throws IOException;
private static native int receive(int socket, byte[] array, int offset,
int length, boolean blocking,
int[] address)
throws IOException;
}

View File

@ -28,8 +28,14 @@ public class MessageFormat extends Format {
public StringBuffer format(Object[] args, StringBuffer target,
FieldPosition p)
{
// todo
return target.append(pattern);
// todo: handle other format substitutions and escapes, and make
// this more efficient:
String result = pattern;
int length = args.length;
for (int i = 0; i < length; i++) {
result = result.replace("{" + i + "}", String.valueOf(args[i]));
}
return target.append(result);
}
public StringBuffer format(Object args, StringBuffer target, FieldPosition p)

View File

@ -15,6 +15,11 @@ public abstract class AbstractList<T> extends AbstractCollection<T>
{
protected int modCount;
public boolean add(T o) {
add(size(), o);
return true;
}
public Iterator<T> iterator() {
return listIterator();
}

View File

@ -17,6 +17,23 @@ public class Arrays {
return asList(a).toString();
}
public static String toString(byte[] a) {
if (a == null) {
return "null";
} else {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < a.length; ++i) {
sb.append(String.valueOf(a[i]));
if (i + 1 != a.length) {
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
}
private static boolean equal(Object a, Object b) {
return (a == null && b == null) || (a != null && a.equals(b));
}