diff options
20 files changed, 641 insertions, 886 deletions
diff --git a/json/src/main/java/org/json/JSONException.java b/json/src/main/java/org/json/JSONException.java index e1efd9f..ddd1016 100644 --- a/json/src/main/java/org/json/JSONException.java +++ b/json/src/main/java/org/json/JSONException.java @@ -23,8 +23,8 @@ package org.json; * <ul> * <li>Attempts to parse or construct malformed documents * <li>Use of null as a name - * <li>Use of numeric types not available to JSON, such as {@link Double#NaN - * NaN} or {@link Double#POSITIVE_INFINITY infinity}. + * <li>Use of numeric types not available to JSON, such as {@link + * Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}. * <li>Lookups using an out of range index or nonexistant name * <li>Type mismatches on lookups * </ul> diff --git a/json/src/main/java/org/json/JSONStringer.java b/json/src/main/java/org/json/JSONStringer.java index fb60bd1..fa22397 100644 --- a/json/src/main/java/org/json/JSONStringer.java +++ b/json/src/main/java/org/json/JSONStringer.java @@ -23,7 +23,40 @@ import java.util.List; // Note: this class was written without inspecting the non-free org.json sourcecode. /** + * Implements {@link JSONObject#toString()} and {@link JSONArray#toString}. Most + * application developers should use those methods directly and disregard this + * API. For example:<pre> + * JSONObject object = ... + * String json = object.toString();</pre> * + * <p>Stringers only encode well-formed JSON strings. In particular: + * <ul> + * <li>The stringer must have exactly one top-level array or object. + * <li>Lexical scopes must be balanced: every call to {@link #array()} must + * have a matching call to {@link #endArray()} and every call to {@link + * #object()} must have a matching call to {@link #endObject()}. + * <li>Arrays may not contain keys (property names). + * <li>Objects must alternate keys (property names) and values. + * <li>Values are inserted with either literal {@link #value(Object) value} + * calls, or by nesting arrays or objects. + * </ul> + * Calls that would result in a malformed JSON string will fail with a + * {@link JSONException}. + * + * <p>This class provides no facility for pretty-printing (ie. indenting) + * output. To encode indented output, use {@link JSONObject#toString(int)} or + * {@link JSONArray#toString(int)}. + * + * <p>Some implementations of the API support at most 20 levels of nesting. + * Attempts to create more than 20 levels of nesting may fail with a {@link + * JSONException}. + * + * <p>Each stringer may be used to encode a single top level value. Instances of + * this class are not thread safe. Although this class is nonfinal, it was not + * designed for inheritance and should not be subclassed. In particular, + * self-use by overridable methods is not specified. See <i>Effective Java</i> + * Item 17, "Design and Document or inheritance or else prohibit it" for further + * information. */ public class JSONStringer { @@ -96,18 +129,40 @@ public class JSONStringer { indent = new String(indentChars); } + /** + * Begins encoding a new array. Each call to this method must be paired with + * a call to {@link #endArray()}. + * + * @return this stringer. + */ public JSONStringer array() throws JSONException { return open(Scope.EMPTY_ARRAY, "["); } + /** + * Ends encoding the current array. + * + * @return this stringer. + */ public JSONStringer endArray() throws JSONException { return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]"); } + /** + * Begins encoding a new object. Each call to this method must be paired + * with a call to {@link #endObject()}. + * + * @return this stringer. + */ public JSONStringer object() throws JSONException { return open(Scope.EMPTY_OBJECT, "{"); } + /** + * Ends encoding the current object. + * + * @return this stringer. + */ public JSONStringer endObject() throws JSONException { return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}"); } @@ -161,6 +216,14 @@ public class JSONStringer { stack.set(stack.size() - 1, topOfStack); } + /** + * Encodes {@code value}. + * + * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean, + * Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs} + * or {@link Double#isInfinite() infinities}. + * @return this stringer. + */ public JSONStringer value(Object value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -192,6 +255,11 @@ public class JSONStringer { return this; } + /** + * Encodes {@code value} to this stringer. + * + * @return this stringer. + */ public JSONStringer value(boolean value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -201,6 +269,13 @@ public class JSONStringer { return this; } + /** + * Encodes {@code value} to this stringer. + * + * @param value a finite value. May not be {@link Double#isNaN() NaNs} or + * {@link Double#isInfinite() infinities}. + * @return this stringer. + */ public JSONStringer value(double value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -210,6 +285,11 @@ public class JSONStringer { return this; } + /** + * Encodes {@code value} to this stringer. + * + * @return this stringer. + */ public JSONStringer value(long value) throws JSONException { if (stack.isEmpty()) { throw new JSONException("Nesting problem"); @@ -281,6 +361,12 @@ public class JSONStringer { } } + /** + * Encodes the key (property name) to this stringer. + * + * @param name the name of the forthcoming value. May not be null. + * @return this stringer. + */ public JSONStringer key(String name) throws JSONException { if (name == null) { throw new JSONException("Names must be non-null"); @@ -331,8 +417,14 @@ public class JSONStringer { } /** - * Although it contradicts the general contract of {@link Object#toString}, - * this method returns null if the stringer contains no data. + * Returns the encoded JSON string. + * + * <p>If invoked with unterminated arrays or unclosed objects, this method's + * return value is undefined. + * + * <p><strong>Warning:</strong> although it contradicts the general contract + * of {@link Object#toString}, this method returns null if the stringer + * contains no data. */ @Override public String toString() { return out.length() == 0 ? null : out.toString(); diff --git a/json/src/main/java/org/json/JSONTokener.java b/json/src/main/java/org/json/JSONTokener.java index e249c74..3b0f593 100644 --- a/json/src/main/java/org/json/JSONTokener.java +++ b/json/src/main/java/org/json/JSONTokener.java @@ -19,7 +19,28 @@ package org.json; // Note: this class was written without inspecting the non-free org.json sourcecode. /** + * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>) + * encoded string into the corresponding object. Most clients of + * this class will use only need the {@link #JSONTokener(String) constructor} + * and {@link #nextValue} method. Example usage: <pre> + * String json = "{" + * + " \"query\": \"Pizza\", " + * + " \"locations\": [ 94043, 90210 ] " + * + "}"; * + * JSONObject object = (JSONObject) new JSONTokener(json).nextValue(); + * String query = object.getString("query"); + * JSONArray locations = object.getJSONArray("locations");</pre> + * + * <p>This parser is lenient. A successful parse does not necessarily indicate + * that the input string is valid JSON. + * + * <p>Each tokener may be used to parse a single JSON string. Instances of this + * class are not thread safe. Although this class is nonfinal, it was not + * designed for inheritance and should not be subclassed. In particular, + * self-use by overridable methods is not specified. See <i>Effective Java</i> + * Item 17, "Design and Document or inheritance or else prohibit it" for further + * information. */ public class JSONTokener { @@ -32,10 +53,22 @@ public class JSONTokener { */ private int pos; + /** + * @param in JSON encoded string. Null is not permitted and will yield a + * tokener that throws {@code NullPointerExceptions} when methods are + * called. + */ public JSONTokener(String in) { this.in = in; } + /** + * Returns the next value from the input. + * + * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean, + * Integer, Long, Double or {@link JSONObject#NULL}. + * @throws JSONException if the input is malformed. + */ public Object nextValue() throws JSONException { int c = nextCleanInternal(); switch (c) { @@ -121,8 +154,12 @@ public class JSONTokener { } /** + * Returns the string up to but not including {@code quote}, unescaping any + * character escape sequences encountered along the way. The opening quote + * should have already been read. This consumes the closing quote, but does + * not include it in the returned string. * - * + * @param quote either ' or ". * @throws NumberFormatException if any unicode escape sequences are * malformed. */ @@ -264,9 +301,8 @@ public class JSONTokener { } /** - * Returns text from the current position until the first of any of the - * given characters or a newline character, excluding that character. The - * position is advanced to the excluded character. + * Returns the string up to but not including any of the given characters or + * a newline character. This does not consume the excluded character. */ private String nextToInternal(String excluded) { int start = pos; @@ -378,10 +414,17 @@ public class JSONTokener { } } - public JSONException syntaxError(String text) { - return new JSONException(text + this); + /** + * Returns an exception containing the given message plus the current + * position and the entire input string. + */ + public JSONException syntaxError(String message) { + return new JSONException(message + this); } + /** + * Returns the current position and the entire input string. + */ @Override public String toString() { // consistent with the original implementation return " at character " + pos + " of " + in; @@ -395,14 +438,26 @@ public class JSONTokener { * implementation and may be used by some clients. */ + /** + * Returns true until the input has been exhausted. + */ public boolean more() { return pos < in.length(); } + /** + * Returns the next available character, or the null character '\0' if all + * input has been exhausted. The return value of this method is ambiguous + * for JSON strings that contain the character '\0'. + */ public char next() { return pos < in.length() ? in.charAt(pos++) : '\0'; } + /** + * Returns the next available character if it equals {@code c}. Otherwise an + * exception is thrown. + */ public char next(char c) throws JSONException { char result = next(); if (result != c) { @@ -411,13 +466,27 @@ public class JSONTokener { return result; } + /** + * Returns the next character that is not whitespace and does not belong to + * a comment. If the input is exhausted before such a character can be + * found, the null character '\0' is returned. The return value of this + * method is ambiguous for JSON strings that contain the character '\0'. + */ public char nextClean() throws JSONException { int nextCleanInt = nextCleanInternal(); return nextCleanInt == -1 ? '\0' : (char) nextCleanInt; } /** - * TODO: note about how this method returns a substring, and could cause a memory leak + * Returns the next {@code length} characters of the input. + * + * <p>The returned string shares its backing character array with this + * tokener's input string. If a reference to the returned string may be held + * indefinitely, you should use {@code new String(result)} to copy it first + * to avoid memory leaks. + * + * @throws JSONException if the remaining input is not long enough to + * satisfy this request. */ public String next(int length) throws JSONException { if (pos + length > in.length()) { @@ -429,7 +498,20 @@ public class JSONTokener { } /** - * TODO: note about how this method returns a substring, and could cause a memory leak + * Returns the {@link String#trim trimmed} string holding the characters up + * to but not including the first of: + * <ul> + * <li>any character in {@code excluded} + * <li>a newline character '\n' + * <li>a carriage return '\r' + * </ul> + * + * <p>The returned string shares its backing character array with this + * tokener's input string. If a reference to the returned string may be held + * indefinitely, you should use {@code new String(result)} to copy it first + * to avoid memory leaks. + * + * @return a possibly-empty string */ public String nextTo(String excluded) { if (excluded == null) { @@ -439,33 +521,54 @@ public class JSONTokener { } /** - * TODO: note about how this method returns a substring, and could cause a memory leak + * Equivalent to {@code nextTo(String.valueOf(excluded))}. */ public String nextTo(char excluded) { return nextToInternal(String.valueOf(excluded)).trim(); } + /** + * Advances past all input up to and including the next occurrence of + * {@code thru}. If the remaining input doesn't contain {@code thru}, the + * input is exhausted. + */ public void skipPast(String thru) { int thruStart = in.indexOf(thru, pos); pos = thruStart == -1 ? in.length() : (thruStart + thru.length()); } + /** + * Advances past all input up to but not including the next occurrence of + * {@code to}. If the remaining input doesn't contain {@code to}, the input + * is unchanged. + */ public char skipTo(char to) { - for (int i = pos, length = in.length(); i < length; i++) { - if (in.charAt(i) == to) { - pos = i; - return to; - } + int index = in.indexOf(to, pos); + if (index != -1) { + pos = index; + return to; + } else { + return '\0'; } - return '\0'; } + /** + * Unreads the most recent character of input. If no input characters have + * been read, the input is unchanged. + */ public void back() { if (--pos == -1) { pos = 0; } } + /** + * Returns the integer [0..15] value for the given hex character, or -1 + * for non-hex input. + * + * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other + * character will yield a -1 result. + */ public static int dehexchar(char hex) { if (hex >= '0' && hex <= '9') { return hex - '0'; diff --git a/luni/src/main/java/java/net/Socket.java b/luni/src/main/java/java/net/Socket.java index 2962b62..208bc09 100644 --- a/luni/src/main/java/java/net/Socket.java +++ b/luni/src/main/java/java/net/Socket.java @@ -61,14 +61,8 @@ public class Socket { private Proxy proxy; - static final int MULTICAST_IF = 1; - - static final int MULTICAST_TTL = 2; - static final int TCP_NODELAY = 4; - static final int FLAG_SHUTDOWN = 8; - static private Logger logger; static private Logger getLogger() { diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java index e2ea82c..7721cbb 100644 --- a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java +++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java @@ -44,14 +44,8 @@ import org.apache.harmony.luni.util.PriviAction; */ public class PlainDatagramSocketImpl extends DatagramSocketImpl { - static final int MULTICAST_IF = 1; - - static final int MULTICAST_TTL = 2; - static final int TCP_NODELAY = 4; - static final int FLAG_SHUTDOWN = 8; - private final static int SO_BROADCAST = 32; final static int IP_MULTICAST_ADD = 19; diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java index 876ad78..8d7ce58 100644 --- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java +++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java @@ -17,9 +17,6 @@ // BEGIN android-note // Address length was changed from long to int for performance reasons. -// Harmony implements INetworkSystem's methods with native methods; Android -// implements them with Java that call through to native wrappers. -// TODO: change the native code to eliminate the wrappers // END android-note package org.apache.harmony.luni.platform; @@ -44,152 +41,56 @@ final class OSNetworkSystem implements INetworkSystem { private static final int ERRORCODE_SOCKET_TIMEOUT = -209; private static final int ERRORCODE_SOCKET_INTERRUPTED = -208; - private static final int INETADDR_REACHABLE = 0; - - // private static boolean isNetworkInited = false; android-removed - private static OSNetworkSystem singleton = new OSNetworkSystem(); - /** - * Answers the unique instance of the OSNetworkSystem. - * - * @return the network system interface instance - */ public static OSNetworkSystem getOSNetworkSystem() { return singleton; } - // Can not be instantiated. private OSNetworkSystem() { - super(); - } - - public void accept(FileDescriptor fdServer, SocketImpl newSocket, - FileDescriptor fdnewSocket, int timeout) throws IOException { - acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout); } - static native void acceptSocketImpl(FileDescriptor fdServer, - SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout) - throws IOException; - - /** - * Associates a local address with a socket. - * - * @param fd - * the socket descriptor - * @param port - * the port number - * @param inetAddress - * address to bind - * @throws SocketException - * thrown if bind operation fails - */ - public void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException { - socketBindImpl(fd, port, inetAddress); - } + public native void accept(FileDescriptor fdServer, SocketImpl newSocket, + FileDescriptor fdnewSocket, int timeout) throws IOException; - static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException; + public native void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException; // BEGIN android-changed (removed unused return value and useless native method) public void connect(FileDescriptor fd, int trafficClass, InetAddress inetAddress, int port) throws IOException{ - connectStreamWithTimeoutSocketImpl(fd, port, 0, trafficClass, inetAddress); + connectStreamWithTimeoutSocket(fd, port, 0, trafficClass, inetAddress); } // END android-changed - public void connectDatagram(FileDescriptor fd, int port, - int trafficClass, InetAddress inetAddress) throws SocketException { - connectDatagramImpl2(fd, port, trafficClass, inetAddress); - } - - static native void connectDatagramImpl2(FileDescriptor aFD, int port, + public native void connectDatagram(FileDescriptor fd, int port, int trafficClass, InetAddress inetAddress) throws SocketException; - public void connectStreamWithTimeoutSocket(FileDescriptor aFD, - int aport, int timeout, int trafficClass, InetAddress inetAddress) - throws IOException { - connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass, - inetAddress); - } - - static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD, - int aport, int timeout, int trafficClass, InetAddress inetAddress) + public native void connectStreamWithTimeoutSocket(FileDescriptor fd, + int port, int timeout, int trafficClass, InetAddress inetAddress) throws IOException; - // BEGIN android-changed - // changed context from Long to byte[] - public int connectWithTimeout(FileDescriptor fd, int timeout, + // BEGIN android-changed: changed context from Long to byte[] + public native int connectWithTimeout(FileDescriptor fd, int timeout, int trafficClass, InetAddress inetAddress, int port, int step, - byte[] context) throws IOException { - return connectWithTimeoutSocketImpl(fd, timeout, trafficClass, - inetAddress, port, step, context); - } - - static native int connectWithTimeoutSocketImpl(FileDescriptor aFD, - int timeout, int trafficClass, InetAddress hostname, int port, int step, - byte[] context); + byte[] context) throws IOException; // END android-changed - public void createDatagramSocket(FileDescriptor fd, - boolean preferIPv4Stack) throws SocketException { - createDatagramSocketImpl(fd, preferIPv4Stack); - } - - /* - * Allocate a datagram socket in the IP stack. The socket is associated with - * the <code>aFD</code>. - * - * @param aFD the FileDescriptor to associate with the socket @param - * preferIPv4Stack IP stack preference if underlying platform is V4/V6 - * @exception SocketException upon an allocation error - */ - static native void createDatagramSocketImpl(FileDescriptor aFD, - boolean preferIPv4Stack) throws SocketException; - - public void createServerStreamSocket(FileDescriptor fd, - boolean preferIPv4Stack) throws SocketException { - createServerStreamSocketImpl(fd, preferIPv4Stack); - } - - /* - * Answer the result of attempting to create a server stream socket in the - * IP stack. Any special options required for server sockets will be set by - * this method. - * - * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4 - * @exception SocketException if an error occurs while creating the socket - */ - static native void createServerStreamSocketImpl(FileDescriptor aFD, - boolean preferIPv4Stack) throws SocketException; - - public void createStreamSocket(FileDescriptor fd, - boolean preferIPv4Stack) throws SocketException { - createStreamSocketImpl(fd, preferIPv4Stack); - } - - static native void createStreamSocketImpl(FileDescriptor aFD, - boolean preferIPv4Stack) throws SocketException; + // TODO: preferIPv4Stack is ignored. + public native void createDatagramSocket(FileDescriptor fd, boolean preferIPv4Stack) + throws SocketException; - /** - * Disconnect the socket to a port and address - *a - * @param fd - * the FileDescriptor associated with the socket - * - * @throws SocketException - * if the disconnect fails - */ - public void disconnectDatagram(FileDescriptor fd) - throws SocketException { - disconnectDatagramImpl(fd); - } + // TODO: preferIPv4Stack is ignored. + public native void createServerStreamSocket(FileDescriptor fd, boolean preferIPv4Stack) + throws SocketException; - static native void disconnectDatagramImpl(FileDescriptor aFD) + // TODO: preferIPv4Stack is ignored. + public native void createStreamSocket(FileDescriptor fd, boolean preferIPv4Stack) throws SocketException; - public InetAddress getHostByAddr(byte[] ipAddress) - throws UnknownHostException { + public native void disconnectDatagram(FileDescriptor fd) throws SocketException; + + // TODO: rewrite callers to skip the middleman. + public InetAddress getHostByAddr(byte[] ipAddress) throws UnknownHostException { // BEGIN android-changed // Wallpaper fix for http://b/1851257. This is a layering violation, // but at least the method has the right return type. @@ -197,20 +98,11 @@ final class OSNetworkSystem implements INetworkSystem { return InetAddress.getByAddress(ipAddress); // END android-changed } - // BEGIN android-removed - // static native InetAddress getHostByAddrImpl(byte[] addr) - // throws UnknownHostException; - // END android-removed - // BEGIN android-changed: remove useless IPv6 check. + // TODO: rewrite callers to skip the middleman. public InetAddress getHostByName(String hostName) throws UnknownHostException { return InetAddress.getByName(hostName); } - // END android-changed - - // BEGIN android-removed - // static native InetAddress getHostByNameImpl(String addr) throws UnknownHostException; - // END android-removed public native String byteArrayToIpString(byte[] address) throws UnknownHostException; @@ -218,111 +110,22 @@ final class OSNetworkSystem implements INetworkSystem { public native byte[] ipStringToByteArray(String address) throws UnknownHostException; - public InetAddress getSocketLocalAddress(FileDescriptor fd) { - return getSocketLocalAddressImpl(fd); - } - static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD); - - public int getSocketLocalPort(FileDescriptor aFD) { - return getSocketLocalPortImpl(aFD); - } - static native int getSocketLocalPortImpl(FileDescriptor aFD); - - /** - * Query the IP stack for the nominated socket option. - * - * @param fd - * the socket descriptor - * @param opt - * the socket option type - * @return the nominated socket option value - * @throws SocketException - * if the option is invalid - */ - public Object getSocketOption(FileDescriptor fd, int opt) - throws SocketException { - return getSocketOptionImpl(fd, opt); - } - - static native Object getSocketOptionImpl(FileDescriptor aFD, int opt) - throws SocketException; - - public native Channel inheritedChannel(); + public native InetAddress getSocketLocalAddress(FileDescriptor fd); - // BEGIN android-removed - // public boolean isReachableByICMP(final InetAddress dest, - // InetAddress source, final int ttl, final int timeout) { - // return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl, - // timeout); - // } + public native int getSocketLocalPort(FileDescriptor fd); - // native int isReachableByICMPImpl(InetAddress addr, - // InetAddress local, int ttl, int timeout); - // END android-removed + public native Object getSocketOption(FileDescriptor fd, int opt) throws SocketException; - public void listenStreamSocket(FileDescriptor aFD, int backlog) - throws SocketException { - listenStreamSocketImpl(aFD, backlog); + public Channel inheritedChannel() { + // Android never has stdin/stdout connected to a socket. + return null; } - static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog) - throws SocketException; - - // BEGIN android-removed: we do this statically, when we start the VM. - // public void oneTimeInitialization(boolean jcl_supports_ipv6); - // native void oneTimeInitializationImpl(boolean jcl_supports_ipv6); - // END android-removed + public native void listenStreamSocket(FileDescriptor fd, int backlog) throws SocketException; - /** - * Peek on the socket, update <code>sender</code> address and answer the - * sender port. - * - * @param fd - * the socket FileDescriptor - * @param sender - * an InetAddress, to be updated with the sender's address - * @param receiveTimeout - * the maximum length of time the socket should block, reading - * @return the sender port - * - * @throws IOException - * upon an read error or timeout - */ - public int peekDatagram(FileDescriptor fd, InetAddress sender, - int receiveTimeout) throws IOException { - return peekDatagramImpl(fd, sender, receiveTimeout); - } - - static native int peekDatagramImpl(FileDescriptor aFD, - InetAddress sender, int receiveTimeout) throws IOException; + public native int peekDatagram(FileDescriptor fd, InetAddress sender, int receiveTimeout) + throws IOException; - /** - * Read available bytes from the given file descriptor into a byte array. - * - * The read has an optional timeout parameter, which if non-zero is the - * length of time that the read will wait on a select call to see if any - * bytes are available for reading. If the timeout expires the method - * returns zero to indicate no bytes were read. - * - * @param fd - * the socket file descriptor to read - * @param data - * the byte array in which to store the results - * @param offset - * the offset into the byte array in which to start reading the - * results - * @param count - * the maximum number of bytes to read - * @param timeout - * the length of time to wait for the bytes, in milliseconds; or - * zero to indicate no timeout applied. When there is no timeout - * applied the read may block based upon socket options. - * @return number of bytes read, or zero if there were no bytes available - * before the timeout occurred, or -1 to indicate the socket is - * closed - * @throws IOException - * if an underlying socket exception occurred - */ public int read(FileDescriptor fd, byte[] data, int offset, int count, int timeout) throws IOException { // BEGIN android-added safety! @@ -337,74 +140,14 @@ final class OSNetworkSystem implements INetworkSystem { static native int readSocketImpl(FileDescriptor aFD, byte[] data, int offset, int count, int timeout) throws IOException; - /** - * Read available bytes from the given file descriptor into OS memory at a - * given address. - * - * @param fd - * the socket file descriptor to read - * @param address - * the address of the memory in which to store the results - * @param count - * the maximum number of bytes to read - * @param timeout - * the length of time to wait for the bytes, in milliseconds - * @return number of bytes read, or zero if there were no bytes available - * before the timeout occurred, or -1 to indicate the socket is - * closed - * @throws IOException - * if an underlying socket exception occurred - */ - public int readDirect(FileDescriptor fd, int address, int count, - int timeout) throws IOException { - return readSocketDirectImpl(fd, address, count, timeout); - } - - static native int readSocketDirectImpl(FileDescriptor aFD, int address, int count, - int timeout) throws IOException; + public native int readDirect(FileDescriptor fd, int address, int count, int timeout) + throws IOException; - /** - * Receive data on the socket into the specified buffer. The packet fields - * <code>data</code> & <code>length</code> are passed in addition to - * <code>packet</code> to eliminate the JNI field access calls. - * - * @param fd - * the socket FileDescriptor - * @param packet - * the DatagramPacket to receive into - * @param data - * the data buffer of the packet - * @param offset - * the offset in the data buffer - * @param length - * the length of the data buffer in the packet - * @param receiveTimeout - * the maximum length of time the socket should block, reading - * @param peek - * indicates to peek at the data - * @return number of data received - * @throws IOException - * upon an read error or timeout - */ - public int receiveDatagram(FileDescriptor fd, DatagramPacket packet, + public native int receiveDatagram(FileDescriptor fd, DatagramPacket packet, byte[] data, int offset, int length, int receiveTimeout, - boolean peek) throws IOException { - return receiveDatagramImpl(fd, packet, data, offset, length, - receiveTimeout, peek); - } - - static native int receiveDatagramImpl(FileDescriptor aFD, - DatagramPacket packet, byte[] data, int offset, int length, - int receiveTimeout, boolean peek) throws IOException; - - public int receiveDatagramDirect(FileDescriptor fd, - DatagramPacket packet, int address, int offset, int length, - int receiveTimeout, boolean peek) throws IOException { - return receiveDatagramDirectImpl(fd, packet, address, offset, length, - receiveTimeout, peek); - } + boolean peek) throws IOException; - static native int receiveDatagramDirectImpl(FileDescriptor aFD, + public native int receiveDatagramDirect(FileDescriptor fd, DatagramPacket packet, int address, int offset, int length, int receiveTimeout, boolean peek) throws IOException; @@ -431,28 +174,14 @@ final class OSNetworkSystem implements INetworkSystem { * @throws IOException * upon an read error or timeout */ - public int recvConnectedDatagram(FileDescriptor fd, - DatagramPacket packet, byte[] data, int offset, int length, - int receiveTimeout, boolean peek) throws IOException { - return recvConnectedDatagramImpl(fd, packet, data, offset, length, - receiveTimeout, peek); - } - - static native int recvConnectedDatagramImpl(FileDescriptor aFD, + public native int recvConnectedDatagram(FileDescriptor fd, DatagramPacket packet, byte[] data, int offset, int length, int receiveTimeout, boolean peek) throws IOException; - public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address, - int offset, int length, int receiveTimeout, boolean peek) - throws IOException { - return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek); - } - - static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD, + public native int recvConnectedDatagramDirect(FileDescriptor fd, DatagramPacket packet, int address, int offset, int length, int receiveTimeout, boolean peek) throws IOException; - public boolean select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs, int numReadable, int numWritable, long timeout, int[] flags) throws SocketException { @@ -465,8 +194,6 @@ final class OSNetworkSystem implements INetworkSystem { return true; } - assert validateFDs(readFDs, writeFDs, numReadable, numWritable) : "Invalid file descriptor arrays"; //$NON-NLS-1$ - // BEGIN android-changed: handle errors in native code return selectImpl(readFDs, writeFDs, numReadable, numWritable, flags, timeout); // END android-changed @@ -478,274 +205,48 @@ final class OSNetworkSystem implements INetworkSystem { long timeout); // END android-changed - /** - * Send the <code>data</code> to the address and port to which the was - * connected and <code>port</code>. - * - * @param fd - * the socket FileDescriptor - * @param data - * the data buffer of the packet - * @param offset - * the offset in the data buffer - * @param length - * the length of the data buffer in the packet - * @param bindToDevice - * not used, current kept in case needed as was the case for - * sendDatagramImpl - * @return number of data send - * @throws IOException - * upon an read error or timeout - */ - public int sendConnectedDatagram(FileDescriptor fd, byte[] data, - int offset, int length, boolean bindToDevice) throws IOException { - return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice); - } - - static native int sendConnectedDatagramImpl(FileDescriptor fd, - byte[] data, int offset, int length, boolean bindToDevice) - throws IOException; + // TODO: bindToDevice is unused. + public native int sendConnectedDatagram(FileDescriptor fd, byte[] data, + int offset, int length, boolean bindToDevice) throws IOException; - public int sendConnectedDatagramDirect(FileDescriptor fd, - int address, int offset, int length, boolean bindToDevice) - throws IOException { - return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice); - } - static native int sendConnectedDatagramDirectImpl(FileDescriptor fd, + // TODO: bindToDevice is unused. + public native int sendConnectedDatagramDirect(FileDescriptor fd, int address, int offset, int length, boolean bindToDevice) throws IOException; - /** - * Send the <code>data</code> to the nominated target <code>address</code> - * and <code>port</code>. These values are derived from the DatagramPacket - * to reduce the field calls within JNI. - * - * @param fd - * the socket FileDescriptor - * @param data - * the data buffer of the packet - * @param offset - * the offset in the data buffer - * @param length - * the length of the data buffer in the packet - * @param port - * the target host port - * @param bindToDevice - * if bind to device - * @param trafficClass - * the traffic class to be used when the datagram is sent - * @param inetAddress - * address to connect to. - * @return number of data send - * - * @throws IOException - * upon an read error or timeout - */ - public int sendDatagram(FileDescriptor fd, byte[] data, int offset, - int length, int port, boolean bindToDevice, int trafficClass, - InetAddress inetAddress) throws IOException { - return sendDatagramImpl(fd, data, offset, length, port, bindToDevice, - trafficClass, inetAddress); - } - - static native int sendDatagramImpl(FileDescriptor fd, byte[] data, int offset, + // TODO: bindToDevice is unused. + public native int sendDatagram(FileDescriptor fd, byte[] data, int offset, int length, int port, boolean bindToDevice, int trafficClass, InetAddress inetAddress) throws IOException; - public int sendDatagram2(FileDescriptor fd, byte[] data, int offset, - int length, int port, InetAddress inetAddress) throws IOException { - return sendDatagramImpl2(fd, data, offset, length, port, inetAddress); - } - - static native int sendDatagramImpl2(FileDescriptor fd, byte[] data, - int offset, int length, int port, InetAddress inetAddress) throws IOException; - + public native int sendDatagram2(FileDescriptor fd, byte[] data, int offset, + int length, int port, InetAddress inetAddress) throws IOException; - public int sendDatagramDirect(FileDescriptor fd, int address, - int offset, int length, int port, boolean bindToDevice, - int trafficClass, InetAddress inetAddress) throws IOException { - return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice, - trafficClass, inetAddress); - } - - static native int sendDatagramDirectImpl(FileDescriptor fd, int address, + // TODO: bindToDevice is unused. + public native int sendDatagramDirect(FileDescriptor fd, int address, int offset, int length, int port, boolean bindToDevice, int trafficClass, InetAddress inetAddress) throws IOException; - public void sendUrgentData(FileDescriptor fd, byte value) { - sendUrgentDataImpl(fd, value); - } + public native void sendUrgentData(FileDescriptor fd, byte value); - static native void sendUrgentDataImpl(FileDescriptor fd, byte value); + public native void setInetAddress(InetAddress sender, byte[] address); - public void setInetAddress(InetAddress sender, byte[] address) { - setInetAddressImpl(sender, address); - } - - native void setInetAddressImpl(InetAddress sender, byte[] address); - - public void setNonBlocking(FileDescriptor fd, boolean block) - throws IOException { - setNonBlockingImpl(fd, block); - } + public native void setNonBlocking(FileDescriptor fd, boolean block) throws IOException; - static native void setNonBlockingImpl(FileDescriptor aFD, boolean block); - - /** - * Set the nominated socket option in the IP stack. - * - * @param aFD - * the socket descriptor @param opt the option selector @param - * optVal the nominated option value - * - * @throws SocketException - * if the option is invalid or cannot be set - */ - public void setSocketOption(FileDescriptor aFD, int opt, - Object optVal) throws SocketException { - setSocketOptionImpl(aFD, opt, optVal); - } + public native void setSocketOption(FileDescriptor fd, int opt, Object optVal) + throws SocketException; - static native void setSocketOptionImpl(FileDescriptor aFD, int opt, - Object optVal) throws SocketException; + public native void shutdownInput(FileDescriptor fd) throws IOException; - public void shutdownInput(FileDescriptor descriptor) throws IOException { - shutdownInputImpl(descriptor); - } + public native void shutdownOutput(FileDescriptor fd) throws IOException; - private native void shutdownInputImpl(FileDescriptor descriptor) - throws IOException; + public native void socketClose(FileDescriptor fd) throws IOException; - public void shutdownOutput(FileDescriptor fd) throws IOException { - shutdownOutputImpl(fd); - } + public native boolean supportsUrgentData(FileDescriptor fd); - private native void shutdownOutputImpl(FileDescriptor descriptor) + public native int write(FileDescriptor fd, byte[] data, int offset, int count) throws IOException; - /** - * Close the socket in the IP stack. - * - * @param fd - * the socket descriptor - */ - public void socketClose(FileDescriptor fd) throws IOException { - socketCloseImpl(fd); - } - - static native void socketCloseImpl(FileDescriptor fD); - - public boolean supportsUrgentData(FileDescriptor fd) { - return supportsUrgentDataImpl(fd); - } - - static native boolean supportsUrgentDataImpl(FileDescriptor fd); - - /* - * Used to check if the file descriptor arrays are valid before passing them - * into the select native call. - */ - private boolean validateFDs(FileDescriptor[] readFDs, - FileDescriptor[] writeFDs) { - for (FileDescriptor fd : readFDs) { - // Also checks fd not null - if (!fd.valid()) { - return false; - } - } - for (FileDescriptor fd : writeFDs) { - if (!fd.valid()) { - return false; - } - } - return true; - } - - private boolean validateFDs(FileDescriptor[] readFDs, - FileDescriptor[] writeFDs, int countRead, int countWrite) { - for (int i = 0; i < countRead; ++i) { - // Also checks fd not null - if (!readFDs[i].valid()) { - return false; - } - } - for (int i = 0; i < countWrite; ++i) { - if (!writeFDs[i].valid()) { - return false; - } - } - return true; - } - - /** - * Write bytes from a byte array to a socket. - * - * @param fd - * the socket on which to write the bytes - * @param data - * the array containing the bytes to be written - * @param offset - * the offset in the byte array from which to take the bytes - * @param count - * the maximum number of bytes to be written. Callers are trusted - * not to send values of length+count that are larger than - * data.length - * @return the actual number of bytes written, which will be between zero - * and count - * @throws IOException - * if there is an underlying socket problem - */ - public int write(FileDescriptor fd, byte[] data, int offset, int count) - throws IOException { - return writeSocketImpl(fd, data, offset, count); - } - - static native int writeSocketImpl(FileDescriptor fd, byte[] data, int offset, - int count) throws IOException; - - /** - * Write bytes from the given address to a socket. - * - * @param fd - * the socket on which to write the bytes - * @param address - * the start address of the bytes to be written - * @param count - * the maximum number of bytes to be written - * @return the actual number of bytes written, which will be between zero - * and count - * @throws IOException - * if there is an underlying socket problem - */ - public int writeDirect(FileDescriptor fd, int address, int offset, int count) - throws IOException { - return writeSocketDirectImpl(fd, address, offset, count); - } - - static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count) + public native int writeDirect(FileDescriptor fd, int address, int offset, int count) throws IOException; - - // BEGIN android-removed - // /** - // * Write given buffers to a socket. The given buffers is a Object array, the - // * element of array must be direct buffer or a byte array to be written. - // * - // * @param fd - // * the socket on which to write the bytes - // * @param buffers - // * the element of array must be direct buffer or a byte array to - // * be written - // * @param offsets - // * the index of the first byte to be write - // * @param counts - // * the maximum number of bytes to be written - // * @param length - // * the size of buffer array - // * @return the actual number of bytes written - // * @throws IOException - // * if there is an underlying socket problem - // */ - // public native int writev(FileDescriptor fd, Object[] buffers, - // int[] offsets, int[] counts, int length) throws IOException; - // END android-removed } diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp index a9b040e..f38f29c 100644 --- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp +++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp @@ -456,7 +456,7 @@ static bool inetAddressToSocketAddress(JNIEnv *env, jobject inetaddress, * * @return a string with the textual representation of the address. */ -static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jclass, +static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jobject, jbyteArray byteArray) { if (byteArray == NULL) { jniThrowNullPointerException(env, NULL); @@ -510,7 +510,7 @@ static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jclass, * * @throws UnknownHostException the IP address was invalid. */ -static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jclass, +static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jobject, jstring javaString) { if (javaString == NULL) { jniThrowNullPointerException(env, NULL); @@ -525,7 +525,7 @@ static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jclass, // Accept IPv6 addresses (only) in square brackets for compatibility. if (ipString[0] == '[' && ipString[byteCount - 1] == ']' && - index(ipString, ':') != NULL) { + strchr(ipString, ':') != NULL) { memmove(ipString, ipString + 1, byteCount - 2); ipString[byteCount - 2] = '\0'; } @@ -1486,22 +1486,16 @@ static int createSocketFileDescriptor(JNIEnv* env, jobject fileDescriptor, return sock; } -static void osNetworkSystem_createStreamSocketImpl(JNIEnv* env, jclass clazz, - jobject fileDescriptor, jboolean preferIPv4Stack) { - // LOGD("ENTER createSocketImpl"); +static void osNetworkSystem_createStreamSocket(JNIEnv* env, jobject, jobject fileDescriptor, jboolean) { createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM); } -static void osNetworkSystem_createDatagramSocketImpl(JNIEnv* env, jclass clazz, - jobject fileDescriptor, jboolean preferIPv4Stack) { - // LOGD("ENTER createDatagramSocketImpl"); - createSocketFileDescriptor(env, fileDescriptor, SOCK_DGRAM); +static void osNetworkSystem_createDatagramSocket(JNIEnv* env, jobject, jobject fd, jboolean) { + createSocketFileDescriptor(env, fd, SOCK_DGRAM); } -static jint osNetworkSystem_readSocketDirectImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_readDirect(JNIEnv* env, jobject, jobject fileDescriptor, jint address, jint count, jint timeout) { - // LOGD("ENTER readSocketDirectImpl"); - int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return 0; @@ -1543,16 +1537,14 @@ static jint osNetworkSystem_readSocketImpl(JNIEnv* env, jclass clazz, } jint address = static_cast<jint>(reinterpret_cast<uintptr_t>(bytes + offset)); - int result = osNetworkSystem_readSocketDirectImpl(env, clazz, + int result = osNetworkSystem_readDirect(env, NULL, fileDescriptor, address, count, timeout); env->ReleaseByteArrayElements(byteArray, bytes, 0); return result; } -static jint osNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_writeDirect(JNIEnv* env, jobject, jobject fileDescriptor, jint address, jint offset, jint count) { - // LOGD("ENTER writeSocketDirectImpl"); - if (count <= 0) { return 0; } @@ -1577,25 +1569,21 @@ static jint osNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz, return bytesSent; } -static jint osNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_write(JNIEnv* env, jobject, jobject fileDescriptor, jbyteArray byteArray, jint offset, jint count) { - // LOGD("ENTER writeSocketImpl"); - jbyte* bytes = env->GetByteArrayElements(byteArray, NULL); if (bytes == NULL) { return -1; } jint address = static_cast<jint>(reinterpret_cast<uintptr_t>(bytes)); - int result = osNetworkSystem_writeSocketDirectImpl(env, clazz, + int result = osNetworkSystem_writeDirect(env, NULL, fileDescriptor, address, offset, count); env->ReleaseByteArrayElements(byteArray, bytes, 0); return result; } -static void osNetworkSystem_setNonBlockingImpl(JNIEnv* env, jclass clazz, +static void osNetworkSystem_setNonBlocking(JNIEnv* env, jobject, jobject fileDescriptor, jboolean nonblocking) { - // LOGD("ENTER setNonBlockingImpl"); - int handle; if (!jniGetFd(env, fileDescriptor, handle)) { return; @@ -1608,11 +1596,9 @@ static void osNetworkSystem_setNonBlockingImpl(JNIEnv* env, jclass clazz, } } -static jint osNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env, - jclass clazz, jobject fileDescriptor, jint timeout, jint trafficClass, +static jint osNetworkSystem_connectWithTimeout(JNIEnv* env, + jobject, jobject fileDescriptor, jint timeout, jint trafficClass, jobject inetAddr, jint port, jint step, jbyteArray passContext) { - // LOGD("ENTER connectWithTimeoutSocketImpl"); - sockaddr_storage address; if (!inetAddressToSocketAddress(env, inetAddr, port, &address)) { return -1; @@ -1657,11 +1643,9 @@ static jint osNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env, return result; } -static void osNetworkSystem_connectStreamWithTimeoutSocketImpl(JNIEnv* env, - jclass clazz, jobject fileDescriptor, jint remotePort, jint timeout, +static void osNetworkSystem_connectStreamWithTimeoutSocket(JNIEnv* env, + jobject, jobject fileDescriptor, jint remotePort, jint timeout, jint trafficClass, jobject inetAddr) { - // LOGD("ENTER connectStreamWithTimeoutSocketImpl"); - int result = 0; struct sockaddr_storage address; jbyte *context = NULL; @@ -1791,10 +1775,8 @@ bail: } } -static void osNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz, - jobject fileDescriptor, jint port, jobject inetAddress) { - // LOGD("ENTER socketBindImpl"); - +static void osNetworkSystem_bind(JNIEnv* env, jobject, jobject fileDescriptor, + jobject inetAddress, jint port) { sockaddr_storage socketAddress; if (!inetAddressToSocketAddress(env, inetAddress, port, &socketAddress)) { return; @@ -1812,10 +1794,8 @@ static void osNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz, } } -static void osNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz, +static void osNetworkSystem_listenStreamSocket(JNIEnv* env, jobject, jobject fileDescriptor, jint backlog) { - // LOGD("ENTER listenStreamSocketImpl"); - int handle; if (!jniGetFd(env, fileDescriptor, handle)) { return; @@ -1828,7 +1808,7 @@ static void osNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz, } } -static void osNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass, +static void osNetworkSystem_accept(JNIEnv* env, jobject, jobject serverFileDescriptor, jobject newSocket, jobject clientFileDescriptor, jint timeout) { // LOGD("ENTER acceptSocketImpl"); @@ -1879,19 +1859,15 @@ static void osNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass, jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd); } -static jboolean osNetworkSystem_supportsUrgentDataImpl(JNIEnv* env, - jclass clazz, jobject fileDescriptor) { - // LOGD("ENTER supportsUrgentDataImpl"); - +static jboolean osNetworkSystem_supportsUrgentData(JNIEnv* env, + jobject, jobject fileDescriptor) { // TODO(enh): do we really need to exclude the invalid file descriptor case? int fd = jniGetFDFromFileDescriptor(env, fileDescriptor); return (fd == -1) ? JNI_FALSE : JNI_TRUE; } -static void osNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz, +static void osNetworkSystem_sendUrgentData(JNIEnv* env, jobject, jobject fileDescriptor, jbyte value) { - // LOGD("ENTER sendUrgentDataImpl"); - int handle; if (!jniGetFd(env, fileDescriptor, handle)) { return; @@ -1903,10 +1879,8 @@ static void osNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz, } } -static void osNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass, +static void osNetworkSystem_connectDatagram(JNIEnv* env, jobject, jobject fileDescriptor, jint port, jint trafficClass, jobject inetAddress) { - // LOGD("ENTER connectDatagramImpl2"); - sockaddr_storage sockAddr; if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) { return; @@ -1923,10 +1897,8 @@ static void osNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass, } } -static void osNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass, +static void osNetworkSystem_disconnectDatagram(JNIEnv* env, jobject, jobject fileDescriptor) { - // LOGD("ENTER disconnectDatagramImpl"); - int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return; @@ -1944,17 +1916,13 @@ static void osNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass, } } -static void osNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject, +static void osNetworkSystem_setInetAddress(JNIEnv* env, jobject, jobject sender, jbyteArray address) { - // LOGD("ENTER setInetAddressImpl"); - env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address); } -static jint osNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_peekDatagram(JNIEnv* env, jobject, jobject fileDescriptor, jobject sender, jint receiveTimeout) { - // LOGD("ENTER peekDatagramImpl"); - int result = pollSelectWait(env, fileDescriptor, receiveTimeout); if (result < 0) { return 0; @@ -1981,15 +1949,13 @@ static jint osNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz, if (sender == NULL) { return -1; } - osNetworkSystem_setInetAddressImpl(env, NULL, sender, senderAddressArray); + osNetworkSystem_setInetAddress(env, NULL, sender, senderAddressArray); return getSocketAddressPort(&sockAddr); } -static jint osNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_receiveDatagramDirect(JNIEnv* env, jobject, jobject fileDescriptor, jobject packet, jint address, jint offset, jint length, jint receiveTimeout, jboolean peek) { - // LOGD("ENTER receiveDatagramDirectImpl"); - int result = pollSelectWait(env, fileDescriptor, receiveTimeout); if (result < 0) { return 0; @@ -2029,11 +1995,9 @@ static jint osNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz, return (jint) actualLength; } -static jint osNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_receiveDatagram(JNIEnv* env, jobject, jobject fd, jobject packet, jbyteArray data, jint offset, jint length, jint receiveTimeout, jboolean peek) { - // LOGD("ENTER receiveDatagramImpl"); - int localLength = (length < 65536) ? length : 65536; jbyte *bytes = (jbyte*) malloc(localLength); if (bytes == NULL) { @@ -2042,7 +2006,7 @@ static jint osNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz, return 0; } - int actualLength = osNetworkSystem_receiveDatagramDirectImpl(env, clazz, fd, + int actualLength = osNetworkSystem_receiveDatagramDirect(env, NULL, fd, packet, (jint)bytes, 0, localLength, receiveTimeout, peek); if (actualLength > 0) { @@ -2053,11 +2017,10 @@ static jint osNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz, return actualLength; } -static jint osNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env, - jclass clazz, jobject fileDescriptor, jobject packet, +static jint osNetworkSystem_recvConnectedDatagramDirect(JNIEnv* env, + jobject, jobject fileDescriptor, jobject packet, jint address, jint offset, jint length, jint receiveTimeout, jboolean peek) { - // LOGD("ENTER receiveConnectedDatagramDirectImpl"); int result = pollSelectWait(env, fileDescriptor, receiveTimeout); if (result < 0) { @@ -2083,11 +2046,9 @@ static jint osNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env, return actualLength; } -static jint osNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_recvConnectedDatagram(JNIEnv* env, jobject, jobject fd, jobject packet, jbyteArray data, jint offset, jint length, jint receiveTimeout, jboolean peek) { - // LOGD("ENTER receiveConnectedDatagramImpl"); - int localLength = (length < 65536) ? length : 65536; jbyte *bytes = (jbyte*) malloc(localLength); if (bytes == NULL) { @@ -2096,8 +2057,8 @@ static jint osNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz, return 0; } - int actualLength = osNetworkSystem_recvConnectedDatagramDirectImpl(env, - clazz, fd, packet, (jint)bytes, 0, localLength, + int actualLength = osNetworkSystem_recvConnectedDatagramDirect(env, + NULL, fd, packet, (jint)bytes, 0, localLength, receiveTimeout, peek); if (actualLength > 0) { @@ -2108,12 +2069,10 @@ static jint osNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz, return actualLength; } -static jint osNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_sendDatagramDirect(JNIEnv* env, jobject, jobject fileDescriptor, jint address, jint offset, jint length, jint port, jboolean bindToDevice, jint trafficClass, jobject inetAddress) { - // LOGD("ENTER sendDatagramDirectImpl"); - int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return -1; @@ -2139,26 +2098,21 @@ static jint osNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz, return bytesSent; } -static jint osNetworkSystem_sendDatagramImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_sendDatagram(JNIEnv* env, jobject, jobject fd, jbyteArray data, jint offset, jint length, jint port, jboolean bindToDevice, jint trafficClass, jobject inetAddress) { - // LOGD("ENTER sendDatagramImpl"); - jbyte *bytes = env->GetByteArrayElements(data, NULL); - int actualLength = osNetworkSystem_sendDatagramDirectImpl(env, clazz, fd, + int actualLength = osNetworkSystem_sendDatagramDirect(env, NULL, fd, (jint)bytes, offset, length, port, bindToDevice, trafficClass, inetAddress); env->ReleaseByteArrayElements(data, bytes, JNI_ABORT); - return actualLength; } -static jint osNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env, - jclass clazz, jobject fileDescriptor, +static jint osNetworkSystem_sendConnectedDatagramDirect(JNIEnv* env, + jobject, jobject fileDescriptor, jint address, jint offset, jint length, jboolean bindToDevice) { - // LOGD("ENTER sendConnectedDatagramDirectImpl"); - int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return 0; @@ -2177,30 +2131,25 @@ static jint osNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env, return bytesSent; } -static jint osNetworkSystem_sendConnectedDatagramImpl(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_sendConnectedDatagram(JNIEnv* env, jobject, jobject fd, jbyteArray data, jint offset, jint length, jboolean bindToDevice) { - // LOGD("ENTER sendConnectedDatagramImpl"); - jbyte *bytes = env->GetByteArrayElements(data, NULL); - int actualLength = osNetworkSystem_sendConnectedDatagramDirectImpl(env, - clazz, fd, (jint)bytes, offset, length, bindToDevice); + int actualLength = osNetworkSystem_sendConnectedDatagramDirect(env, + NULL, fd, (jint)bytes, offset, length, bindToDevice); env->ReleaseByteArrayElements(data, bytes, JNI_ABORT); return actualLength; } -static void osNetworkSystem_createServerStreamSocketImpl(JNIEnv* env, - jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) { - // LOGD("ENTER createServerStreamSocketImpl"); - - int handle = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM); - if (handle < 0) { - return; +static void osNetworkSystem_createServerStreamSocket(JNIEnv* env, jobject, + jobject fileDescriptor, jboolean) { + int fd = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM); + if (fd != -1) { + // TODO: we could actually do this in Java. (and check for errors!) + int value = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int)); } - - int value = 1; - setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int)); } static void doShutdown(JNIEnv* env, jobject fileDescriptor, int how) { @@ -2214,21 +2163,17 @@ static void doShutdown(JNIEnv* env, jobject fileDescriptor, int how) { } } -static void osNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject, - jobject fileDescriptor) { - doShutdown(env, fileDescriptor, SHUT_RD); +static void osNetworkSystem_shutdownInput(JNIEnv* env, jobject, jobject fd) { + doShutdown(env, fd, SHUT_RD); } -static void osNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject, - jobject fileDescriptor) { - doShutdown(env, fileDescriptor, SHUT_WR); +static void osNetworkSystem_shutdownOutput(JNIEnv* env, jobject, jobject fd) { + doShutdown(env, fd, SHUT_WR); } -static jint osNetworkSystem_sendDatagramImpl2(JNIEnv* env, jclass clazz, +static jint osNetworkSystem_sendDatagram2(JNIEnv* env, jobject, jobject fileDescriptor, jbyteArray data, jint offset, jint length, jint port, jobject inetAddress) { - // LOGD("ENTER sendDatagramImpl2"); - sockaddr_storage sockAddr; if (inetAddress != NULL) { if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) { @@ -2316,7 +2261,7 @@ static bool translateFdSet(JNIEnv* env, jobjectArray fdArray, jint count, fd_set return true; } -static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass clazz, +static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass, jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC, jint countWriteC, jintArray outFlags, jlong timeoutMs) { // LOGD("ENTER selectImpl"); @@ -2367,10 +2312,8 @@ static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass clazz, return okay; } -static jobject osNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env, - jclass, jobject fileDescriptor) { - // LOGD("ENTER getSocketLocalAddressImpl"); - +static jobject osNetworkSystem_getSocketLocalAddress(JNIEnv* env, + jobject, jobject fileDescriptor) { int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return NULL; @@ -2390,10 +2333,8 @@ static jobject osNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env, return socketAddressToInetAddress(env, &addr); } -static jint osNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass, +static jint osNetworkSystem_getSocketLocalPort(JNIEnv* env, jobject, jobject fileDescriptor) { - // LOGD("ENTER getSocketLocalPortImpl"); - int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return 0; @@ -2413,10 +2354,8 @@ static jint osNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass, return getSocketAddressPort(&addr); } -static jobject osNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz, +static jobject osNetworkSystem_getSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint anOption) { - // LOGD("ENTER getSocketOptionImpl"); - int intValue = 0; socklen_t intSize = sizeof(int); int result; @@ -2628,10 +2567,8 @@ static jobject osNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz, } -static void osNetworkSystem_setSocketOptionImpl(JNIEnv* env, jclass clazz, +static void osNetworkSystem_setSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint anOption, jobject optVal) { - // LOGD("ENTER setSocketOptionImpl"); - int result; int intVal; socklen_t intSize = sizeof(int); @@ -2886,10 +2823,7 @@ static void osNetworkSystem_setSocketOptionImpl(JNIEnv* env, jclass clazz, } } -static void osNetworkSystem_socketCloseImpl(JNIEnv* env, jclass clazz, - jobject fileDescriptor) { - // LOGD("ENTER socketCloseImpl"); - +static void osNetworkSystem_socketClose(JNIEnv* env, jobject, jobject fileDescriptor) { int fd; if (!jniGetFd(env, fileDescriptor, fd)) { return; @@ -2900,55 +2834,49 @@ static void osNetworkSystem_socketCloseImpl(JNIEnv* env, jclass clazz, close(fd); } -static jobject osNetworkSystem_inheritedChannel(JNIEnv* env, jobject obj) { - // Android never has stdin/stdout connected to a socket. - return NULL; -} - /* * JNI registration. */ static JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ - { "createStreamSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createStreamSocketImpl }, - { "createDatagramSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createDatagramSocketImpl }, - { "readSocketImpl", "(Ljava/io/FileDescriptor;[BIII)I", (void*) osNetworkSystem_readSocketImpl }, - { "readSocketDirectImpl", "(Ljava/io/FileDescriptor;III)I", (void*) osNetworkSystem_readSocketDirectImpl }, - { "writeSocketImpl", "(Ljava/io/FileDescriptor;[BII)I", (void*) osNetworkSystem_writeSocketImpl }, - { "writeSocketDirectImpl", "(Ljava/io/FileDescriptor;III)I", (void*) osNetworkSystem_writeSocketDirectImpl }, - { "setNonBlockingImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_setNonBlockingImpl }, - { "connectWithTimeoutSocketImpl", "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I", (void*) osNetworkSystem_connectWithTimeoutSocketImpl }, - { "connectStreamWithTimeoutSocketImpl","(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V", (void*) osNetworkSystem_connectStreamWithTimeoutSocketImpl }, - { "socketBindImpl", "(Ljava/io/FileDescriptor;ILjava/net/InetAddress;)V", (void*) osNetworkSystem_socketBindImpl }, - { "listenStreamSocketImpl", "(Ljava/io/FileDescriptor;I)V", (void*) osNetworkSystem_listenStreamSocketImpl }, - { "acceptSocketImpl", "(Ljava/io/FileDescriptor;Ljava/net/SocketImpl;Ljava/io/FileDescriptor;I)V",(void*) osNetworkSystem_acceptSocketImpl }, - { "supportsUrgentDataImpl", "(Ljava/io/FileDescriptor;)Z", (void*) osNetworkSystem_supportsUrgentDataImpl }, - { "sendUrgentDataImpl", "(Ljava/io/FileDescriptor;B)V", (void*) osNetworkSystem_sendUrgentDataImpl }, - { "connectDatagramImpl2", "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V", (void*) osNetworkSystem_connectDatagramImpl2 }, - { "disconnectDatagramImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_disconnectDatagramImpl }, - { "peekDatagramImpl", "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I", (void*) osNetworkSystem_peekDatagramImpl }, - { "receiveDatagramImpl", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I", (void*) osNetworkSystem_receiveDatagramImpl }, - { "receiveDatagramDirectImpl", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I", (void*) osNetworkSystem_receiveDatagramDirectImpl }, - { "recvConnectedDatagramImpl", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I", (void*) osNetworkSystem_recvConnectedDatagramImpl }, - { "recvConnectedDatagramDirectImpl", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I", (void*) osNetworkSystem_recvConnectedDatagramDirectImpl }, - { "sendDatagramImpl", "(Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagramImpl }, - { "sendDatagramDirectImpl", "(Ljava/io/FileDescriptor;IIIIZILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagramDirectImpl }, - { "sendConnectedDatagramImpl", "(Ljava/io/FileDescriptor;[BIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramImpl }, - { "sendConnectedDatagramDirectImpl", "(Ljava/io/FileDescriptor;IIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramDirectImpl }, - { "createServerStreamSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createServerStreamSocketImpl }, - { "shutdownInputImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownInputImpl }, - { "shutdownOutputImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownOutputImpl }, - { "sendDatagramImpl2", "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagramImpl2 }, - { "selectImpl", "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z", (void*) osNetworkSystem_selectImpl }, - { "getSocketLocalAddressImpl", "(Ljava/io/FileDescriptor;)Ljava/net/InetAddress;", (void*) osNetworkSystem_getSocketLocalAddressImpl }, - { "getSocketLocalPortImpl", "(Ljava/io/FileDescriptor;)I", (void*) osNetworkSystem_getSocketLocalPortImpl }, - { "getSocketOptionImpl", "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;", (void*) osNetworkSystem_getSocketOptionImpl }, - { "setSocketOptionImpl", "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V", (void*) osNetworkSystem_setSocketOptionImpl }, - { "socketCloseImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_socketCloseImpl }, - { "setInetAddressImpl", "(Ljava/net/InetAddress;[B)V", (void*) osNetworkSystem_setInetAddressImpl }, - { "inheritedChannel", "()Ljava/nio/channels/Channel;", (void*) osNetworkSystem_inheritedChannel }, - { "byteArrayToIpString", "([B)Ljava/lang/String;", (void*) osNetworkSystem_byteArrayToIpString }, - { "ipStringToByteArray", "(Ljava/lang/String;)[B", (void*) osNetworkSystem_ipStringToByteArray }, + { "accept", "(Ljava/io/FileDescriptor;Ljava/net/SocketImpl;Ljava/io/FileDescriptor;I)V",(void*) osNetworkSystem_accept }, + { "bind", "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V", (void*) osNetworkSystem_bind }, + { "byteArrayToIpString", "([B)Ljava/lang/String;", (void*) osNetworkSystem_byteArrayToIpString }, + { "connectDatagram", "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V", (void*) osNetworkSystem_connectDatagram }, + { "connectStreamWithTimeoutSocket", "(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V", (void*) osNetworkSystem_connectStreamWithTimeoutSocket }, + { "connectWithTimeout", "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I", (void*) osNetworkSystem_connectWithTimeout }, + { "createDatagramSocket", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createDatagramSocket }, + { "createServerStreamSocket", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createServerStreamSocket }, + { "createStreamSocket", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createStreamSocket }, + { "disconnectDatagram", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_disconnectDatagram }, + { "getSocketLocalAddress", "(Ljava/io/FileDescriptor;)Ljava/net/InetAddress;", (void*) osNetworkSystem_getSocketLocalAddress }, + { "getSocketLocalPort", "(Ljava/io/FileDescriptor;)I", (void*) osNetworkSystem_getSocketLocalPort }, + { "getSocketOption", "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;", (void*) osNetworkSystem_getSocketOption }, + { "ipStringToByteArray", "(Ljava/lang/String;)[B", (void*) osNetworkSystem_ipStringToByteArray }, + { "listenStreamSocket", "(Ljava/io/FileDescriptor;I)V", (void*) osNetworkSystem_listenStreamSocket }, + { "peekDatagram", "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I", (void*) osNetworkSystem_peekDatagram }, + { "readDirect", "(Ljava/io/FileDescriptor;III)I", (void*) osNetworkSystem_readDirect }, + { "readSocketImpl", "(Ljava/io/FileDescriptor;[BIII)I", (void*) osNetworkSystem_readSocketImpl }, + { "receiveDatagramDirect", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I", (void*) osNetworkSystem_receiveDatagramDirect }, + { "receiveDatagram", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I", (void*) osNetworkSystem_receiveDatagram }, + { "recvConnectedDatagramDirect", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I", (void*) osNetworkSystem_recvConnectedDatagramDirect }, + { "recvConnectedDatagram", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I", (void*) osNetworkSystem_recvConnectedDatagram }, + { "selectImpl", "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z", (void*) osNetworkSystem_selectImpl }, + { "sendConnectedDatagramDirect", "(Ljava/io/FileDescriptor;IIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramDirect }, + { "sendConnectedDatagram", "(Ljava/io/FileDescriptor;[BIIZ)I", (void*) osNetworkSystem_sendConnectedDatagram }, + { "sendDatagramDirect", "(Ljava/io/FileDescriptor;IIIIZILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagramDirect }, + { "sendDatagram", "(Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagram }, + { "sendDatagram2", "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I", (void*) osNetworkSystem_sendDatagram2 }, + { "sendUrgentData", "(Ljava/io/FileDescriptor;B)V", (void*) osNetworkSystem_sendUrgentData }, + { "setInetAddress", "(Ljava/net/InetAddress;[B)V", (void*) osNetworkSystem_setInetAddress }, + { "setNonBlocking", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_setNonBlocking }, + { "setSocketOption", "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V", (void*) osNetworkSystem_setSocketOption }, + { "shutdownInput", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownInput }, + { "shutdownOutput", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownOutput }, + { "socketClose", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_socketClose }, + { "supportsUrgentData", "(Ljava/io/FileDescriptor;)Z", (void*) osNetworkSystem_supportsUrgentData }, + { "writeDirect", "(Ljava/io/FileDescriptor;III)I", (void*) osNetworkSystem_writeDirect }, + { "write", "(Ljava/io/FileDescriptor;[BII)I", (void*) osNetworkSystem_write }, }; int register_org_apache_harmony_luni_platform_OSNetworkSystem(JNIEnv* env) { diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java index 22d1b4a..3aa063c 100644 --- a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java +++ b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java @@ -46,15 +46,6 @@ import org.apache.harmony.luni.platform.Platform; public class ServerSocketChannelImpl extends ServerSocketChannel implements FileDescriptorHandler { - // status un-init, not initialized. - private static final int SERVER_STATUS_UNINIT = -1; - - // status after open and before closed. - private static final int SERVER_STATUS_OPEN = 0; - - // status closed. - private static final int SERVER_STATUS_CLOSED = 1; - // The fd to interact with native code private final FileDescriptor fd; @@ -63,8 +54,6 @@ public class ServerSocketChannelImpl extends ServerSocketChannel implements private final SocketImpl impl; - int status = SERVER_STATUS_UNINIT; - // whether the socket is bound boolean isBound = false; @@ -77,7 +66,6 @@ public class ServerSocketChannelImpl extends ServerSocketChannel implements */ public ServerSocketChannelImpl(SelectorProvider sp) throws IOException { super(sp); - status = SERVER_STATUS_OPEN; fd = new FileDescriptor(); Platform.getNetworkSystem().createStreamSocket(fd, NetUtil.preferIPv4Stack()); @@ -89,7 +77,6 @@ public class ServerSocketChannelImpl extends ServerSocketChannel implements @SuppressWarnings("unused") private ServerSocketChannelImpl() throws IOException { super(SelectorProvider.provider()); - status = SERVER_STATUS_OPEN; fd = new FileDescriptor(); impl = new PlainServerSocketImpl(fd); socket = new ServerSocketAdapter(impl, this); @@ -175,7 +162,6 @@ public class ServerSocketChannelImpl extends ServerSocketChannel implements * @see java.nio.channels.spi.AbstractSelectableChannel#implCloseSelectableChannel() */ synchronized protected void implCloseSelectableChannel() throws IOException { - status = SERVER_STATUS_CLOSED; if (!socket.isClosed()) { socket.close(); } @@ -296,7 +282,6 @@ public class ServerSocketChannelImpl extends ServerSocketChannel implements } else { super.close(); } - channelImpl.status = SERVER_STATUS_CLOSED; } } } diff --git a/security/src/main/files/certimport.sh b/security/src/main/files/certimport.sh index ca36a70..1f489e6 100755 --- a/security/src/main/files/certimport.sh +++ b/security/src/main/files/certimport.sh @@ -1,6 +1,39 @@ #!/bin/bash +# +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# certimport.sh recreates the cacerts.bks file from the x509 CA +# certificates in the cacerts directory. +# +# By convention, the filenames in the cacerts directory are in the +# format of <hash>.<n> where "hash" is the subject hash produced by: +# +# openssl x509 -subject_hash -in filename +# +# and the "n" is the the depth of the certificate along a chain, i.e. +# .0 for roots, .1 for an intermediate one level deep, etc. +# +# The filename itself is not important, and is around just for convention sake. +# +# usage is simply running ./certimport.sh from the scripts directory +# # java version >= 1.6 is required for this script. +# # This script was tested to work with bouncycastle 1.32. +# set -x set -e diff --git a/tools/runner/java/dalvik/runner/CaliperFinder.java b/tools/runner/java/dalvik/runner/CaliperFinder.java index 3609471..1facf88 100644 --- a/tools/runner/java/dalvik/runner/CaliperFinder.java +++ b/tools/runner/java/dalvik/runner/CaliperFinder.java @@ -25,7 +25,7 @@ import java.io.File; class CaliperFinder extends NamingPatternCodeFinder { @Override protected boolean matches(File file) { - return file.getName().endsWith("Benchmark.java"); + return super.matches(file) && file.getName().endsWith("Benchmark.java"); } @Override protected String testName(File file) { diff --git a/tools/runner/java/dalvik/runner/JUnitFinder.java b/tools/runner/java/dalvik/runner/JUnitFinder.java index 131a8cf..ba80ac1 100644 --- a/tools/runner/java/dalvik/runner/JUnitFinder.java +++ b/tools/runner/java/dalvik/runner/JUnitFinder.java @@ -24,7 +24,7 @@ import java.io.File; class JUnitFinder extends NamingPatternCodeFinder { @Override protected boolean matches(File file) { - return file.getName().endsWith("Test.java"); + return super.matches(file) && file.getName().endsWith("Test.java"); } // TODO: try to get names for each method? diff --git a/tools/runner/java/dalvik/runner/MainFinder.java b/tools/runner/java/dalvik/runner/MainFinder.java index 282969f..0923f53 100644 --- a/tools/runner/java/dalvik/runner/MainFinder.java +++ b/tools/runner/java/dalvik/runner/MainFinder.java @@ -23,10 +23,6 @@ import java.io.File; */ class MainFinder extends NamingPatternCodeFinder { - @Override protected boolean matches(File file) { - return file.getName().endsWith(".java"); - } - @Override protected String testName(File file) { return "main"; } diff --git a/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java b/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java index 19c9df2..ae8309f 100644 --- a/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java +++ b/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java @@ -44,7 +44,8 @@ abstract class NamingPatternCodeFinder implements CodeFinder { * Returns true if {@code file} contains a test class of this type. */ protected boolean matches(File file) { - return file.getName().endsWith(".java"); + return (!file.getName().startsWith(".") + && file.getName().endsWith(".java")); } protected abstract String testName(File file); diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java index 56a4817..c601de6 100644 --- a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java +++ b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java @@ -36,49 +36,19 @@ public final class AttrImpl extends NodeImpl implements Attr { // Maintained by ElementImpl. ElementImpl ownerElement; - - private boolean namespaceAware; - boolean isId; - - private String namespaceURI; - private String localName; + boolean namespaceAware; + String namespaceURI; + String prefix; + String localName; - private String prefix; - private String value; AttrImpl(DocumentImpl document, String namespaceURI, String qualifiedName) { super(document); - namespaceAware = true; - this.namespaceURI = namespaceURI; - - if (qualifiedName == null || "".equals(qualifiedName)) { - throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName); - } - - int prefixSeparator = qualifiedName.lastIndexOf(":"); - if (prefixSeparator != -1) { - setPrefix(qualifiedName.substring(0, prefixSeparator)); - qualifiedName = qualifiedName.substring(prefixSeparator + 1); - } - - localName = qualifiedName; - - if ("".equals(localName)) { - throw new DOMException(DOMException.NAMESPACE_ERR, localName); - } - - if ("xmlns".equals(localName) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) { - throw new DOMException(DOMException.NAMESPACE_ERR, localName); - } - - if (!DocumentImpl.isXMLIdentifier(localName)) { - throw new DOMException(DOMException.INVALID_CHARACTER_ERR, localName); - } - + setNameNS(this, namespaceURI, qualifiedName); value = ""; } diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java index b662a13..3106c3f 100644 --- a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java +++ b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java @@ -85,6 +85,6 @@ public final class DOMImplementationImpl implements DOMImplementation { } public Object getFeature(String feature, String version) { - throw new UnsupportedOperationException(); // TODO + return hasFeature(feature, version) ? this : null; } } diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java index c677e58..56283a8 100644 --- a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java +++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java @@ -299,6 +299,16 @@ public final class DocumentImpl extends InnerNodeImpl implements Document { } } + public Node renameNode(Node node, String namespaceURI, String qualifiedName) { + if (node.getOwnerDocument() != this) { + throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null); + } + + setNameNS((NodeImpl) node, namespaceURI, qualifiedName); + notifyUserDataHandlers(UserDataHandler.NODE_RENAMED, node, null); + return node; + } + public AttrImpl createAttribute(String name) { return new AttrImpl(this, name); } @@ -467,11 +477,6 @@ public final class DocumentImpl extends InnerNodeImpl implements Document { ((DOMConfigurationImpl) getDomConfig()).normalize(root); } - public Node renameNode(Node n, String namespaceURI, String qualifiedName) { - // TODO: callback the UserDataHandler with a NODE_RENAMED event - throw new UnsupportedOperationException(); // TODO - } - /** * Returns a map with the user data objects attached to the specified node. * This map is readable and writable. diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java index c3e5a2e..cbc4570 100644 --- a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java +++ b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java @@ -39,37 +39,16 @@ import java.util.List; */ public class ElementImpl extends InnerNodeImpl implements Element { - private boolean namespaceAware; - - private String namespaceURI; - - private String prefix; - - private String localName; + boolean namespaceAware; + String namespaceURI; + String prefix; + String localName; private List<AttrImpl> attributes = new ArrayList<AttrImpl>(); ElementImpl(DocumentImpl document, String namespaceURI, String qualifiedName) { super(document); - - this.namespaceAware = true; - this.namespaceURI = namespaceURI; - - if (qualifiedName == null || "".equals(qualifiedName)) { - throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName); - } - - int p = qualifiedName.lastIndexOf(":"); - if (p != -1) { - setPrefix(qualifiedName.substring(0, p)); - qualifiedName = qualifiedName.substring(p + 1); - } - - if (!DocumentImpl.isXMLIdentifier(qualifiedName)) { - throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName); - } - - this.localName = qualifiedName; + setNameNS(this, namespaceURI, qualifiedName); } ElementImpl(DocumentImpl document, String name) { @@ -383,7 +362,7 @@ public class ElementImpl extends InnerNodeImpl implements Element { public void setPrefix(String prefix) { this.prefix = validatePrefix(prefix, namespaceAware, namespaceURI); } - + public class ElementAttrNamedNodeMapImpl implements NamedNodeMap { public int getLength() { diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java index 359a042..8beb18c 100644 --- a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java +++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java @@ -198,7 +198,7 @@ public abstract class NodeImpl implements Node { * @param namespaceAware whether this node is namespace aware * @param namespaceURI this node's namespace URI */ - protected String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) { + static String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) { if (!namespaceAware) { throw new DOMException(DOMException.NAMESPACE_ERR, prefix); } @@ -216,6 +216,58 @@ public abstract class NodeImpl implements Node { } /** + * Sets the element or attribute node to be namespace-aware and assign it + * the specified name and namespace URI. + * + * @param node an AttrImpl or ElementImpl node. + * @param namespaceURI this node's namespace URI. May be null. + * @param qualifiedName a possibly-prefixed name like "img" or "html:img". + */ + static void setNameNS(NodeImpl node, String namespaceURI, String qualifiedName) { + if (qualifiedName == null) { + throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName); + } + + String prefix = null; + int p = qualifiedName.lastIndexOf(":"); + if (p != -1) { + prefix = validatePrefix(qualifiedName.substring(0, p), true, namespaceURI); + qualifiedName = qualifiedName.substring(p + 1); + } + + if (!DocumentImpl.isXMLIdentifier(qualifiedName)) { + throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName); + } + + switch (node.getNodeType()) { + case ATTRIBUTE_NODE: + if ("xmlns".equals(qualifiedName) + && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) { + throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName); + } + + AttrImpl attr = (AttrImpl) node; + attr.namespaceAware = true; + attr.namespaceURI = namespaceURI; + attr.prefix = prefix; + attr.localName = qualifiedName; + break; + + case ELEMENT_NODE: + ElementImpl element = (ElementImpl) node; + element.namespaceAware = true; + element.namespaceURI = namespaceURI; + element.prefix = prefix; + element.localName = qualifiedName; + break; + + default: + throw new DOMException(DOMException.NOT_SUPPORTED_ERR, + "Cannot rename nodes of type " + node.getNodeType()); + } + } + + /** * Checks whether a required string matches an actual string. This utility * method is used for comparing namespaces and such. It takes into account * null arguments and the "*" special case. diff --git a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java index 3f0d2cb..0438e98 100644 --- a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java +++ b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java @@ -73,7 +73,7 @@ import java.util.List; * suite zip file from the OASIS project site.</li> * <li>Unzip. * <li>Copy the files to a device: <code>adb shell mkdir /data/oasis ; - * adb push ./XSLT-Conformance-TC /data/oasis</code>. + * adb push ./XSLT-Conformance-TC/data/oasis</code>. * <li>Invoke this class' main method, passing the on-device path to the test * suite's <code>catalog.xml</code> file as an argument. * </ul> diff --git a/xml/src/test/java/tests/xml/DomTest.java b/xml/src/test/java/tests/xml/DomTest.java index 3bafb78..2f364d0 100644 --- a/xml/src/test/java/tests/xml/DomTest.java +++ b/xml/src/test/java/tests/xml/DomTest.java @@ -61,6 +61,7 @@ import java.util.regex.Pattern; import static org.w3c.dom.UserDataHandler.NODE_ADOPTED; import static org.w3c.dom.UserDataHandler.NODE_CLONED; import static org.w3c.dom.UserDataHandler.NODE_IMPORTED; +import static org.w3c.dom.UserDataHandler.NODE_RENAMED; /** * Construct a DOM and then interrogate it. @@ -512,25 +513,25 @@ public class DomTest extends TestCase { } public void testCoreFeature() { - assertTrue(domImplementation.hasFeature("Core", null)); - assertTrue(domImplementation.hasFeature("Core", "")); - assertTrue(domImplementation.hasFeature("Core", "1.0")); - assertTrue(domImplementation.hasFeature("Core", "2.0")); - assertTrue(domImplementation.hasFeature("Core", "3.0")); - assertTrue(domImplementation.hasFeature("CORE", "3.0")); - assertTrue(domImplementation.hasFeature("+Core", "3.0")); - assertFalse(domImplementation.hasFeature("Core", "4.0")); + assertFeature("Core", null); + assertFeature("Core", ""); + assertFeature("Core", "1.0"); + assertFeature("Core", "2.0"); + assertFeature("Core", "3.0"); + assertFeature("CORE", "3.0"); + assertFeature("+Core", "3.0"); + assertNoFeature("Core", "4.0"); } public void testXmlFeature() { - assertTrue(domImplementation.hasFeature("XML", null)); - assertTrue(domImplementation.hasFeature("XML", "")); - assertTrue(domImplementation.hasFeature("XML", "1.0")); - assertTrue(domImplementation.hasFeature("XML", "2.0")); - assertTrue(domImplementation.hasFeature("XML", "3.0")); - assertTrue(domImplementation.hasFeature("Xml", "3.0")); - assertTrue(domImplementation.hasFeature("+XML", "3.0")); - assertFalse(domImplementation.hasFeature("XML", "4.0")); + assertFeature("XML", null); + assertFeature("XML", ""); + assertFeature("XML", "1.0"); + assertFeature("XML", "2.0"); + assertFeature("XML", "3.0"); + assertFeature("Xml", "3.0"); + assertFeature("+XML", "3.0"); + assertNoFeature("XML", "4.0"); } /** @@ -538,26 +539,35 @@ public class DomTest extends TestCase { * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Document3-version */ public void testXmlVersionFeature() { - String message = "This implementation does not support the XMLVersion feature"; - assertTrue(message, domImplementation.hasFeature("XMLVersion", null)); - assertTrue(message, domImplementation.hasFeature("XMLVersion", "")); - assertTrue(message, domImplementation.hasFeature("XMLVersion", "1.0")); - assertTrue(message, domImplementation.hasFeature("XMLVersion", "1.1")); - assertTrue(message, domImplementation.hasFeature("XMLVERSION", "1.1")); - assertTrue(message, domImplementation.hasFeature("+XMLVersion", "1.1")); - assertFalse(domImplementation.hasFeature("XMLVersion", "1.2")); - assertFalse(domImplementation.hasFeature("XMLVersion", "2.0")); - assertFalse(domImplementation.hasFeature("XMLVersion", "2.0")); + assertFeature("XMLVersion", null); + assertFeature("XMLVersion", ""); + assertFeature("XMLVersion", "1.0"); + assertFeature("XMLVersion", "1.1"); + assertFeature("XMLVERSION", "1.1"); + assertFeature("+XMLVersion", "1.1"); + assertNoFeature("XMLVersion", "1.2"); + assertNoFeature("XMLVersion", "2.0"); + assertNoFeature("XMLVersion", "2.0"); } public void testLsFeature() { - assertTrue("This implementation does not support the LS feature", - domImplementation.hasFeature("LS", "3.0")); + assertFeature("LS", "3.0"); } public void testElementTraversalFeature() { - assertTrue("This implementation does not support the ElementTraversal feature", - domImplementation.hasFeature("ElementTraversal", "1.0")); + assertFeature("ElementTraversal", "1.0"); + } + + private void assertFeature(String feature, String version) { + String message = "This implementation is expected to support " + + feature + " v. " + version + " but does not."; + assertTrue(message, domImplementation.hasFeature(feature, version)); + assertNotNull(message, domImplementation.getFeature(feature, version)); + } + + private void assertNoFeature(String feature, String version) { + assertFalse(domImplementation.hasFeature(feature, version)); + assertNull(domImplementation.getFeature(feature, version)); } public void testIsSupported() { @@ -1189,6 +1199,118 @@ public class DomTest extends TestCase { assertFalse(typeInfo.isDerivedFrom("x", "y", TypeInfo.DERIVATION_UNION)); } + public void testRenameElement() { + document.renameNode(description, null, "desc"); + assertEquals("desc", description.getTagName()); + assertEquals("desc", description.getLocalName()); + assertEquals(null, description.getPrefix()); + assertEquals(null, description.getNamespaceURI()); + } + + public void testRenameElementWithPrefix() { + try { + document.renameNode(description, null, "a:desc"); + fail(); + } catch (DOMException e) { + } + } + + public void testRenameElementWithNamespace() { + document.renameNode(description, "http://sales", "desc"); + assertEquals("desc", description.getTagName()); + assertEquals("desc", description.getLocalName()); + assertEquals(null, description.getPrefix()); + assertEquals("http://sales", description.getNamespaceURI()); + } + + public void testRenameElementWithPrefixAndNamespace() { + document.renameNode(description, "http://sales", "a:desc"); + assertEquals("a:desc", description.getTagName()); + assertEquals("desc", description.getLocalName()); + assertEquals("a", description.getPrefix()); + assertEquals("http://sales", description.getNamespaceURI()); + } + + public void testRenameAttribute() { + document.renameNode(deluxe, null, "special"); + assertEquals("special", deluxe.getName()); + assertEquals("special", deluxe.getLocalName()); + assertEquals(null, deluxe.getPrefix()); + assertEquals(null, deluxe.getNamespaceURI()); + } + + public void testRenameAttributeWithPrefix() { + try { + document.renameNode(deluxe, null, "a:special"); + fail(); + } catch (DOMException e) { + } + } + + public void testRenameAttributeWithNamespace() { + document.renameNode(deluxe, "http://sales", "special"); + assertEquals("special", deluxe.getName()); + assertEquals("special", deluxe.getLocalName()); + assertEquals(null, deluxe.getPrefix()); + assertEquals("http://sales", deluxe.getNamespaceURI()); + } + + public void testRenameAttributeWithPrefixAndNamespace() { + document.renameNode(deluxe, "http://sales", "a:special"); + assertEquals("a:special", deluxe.getName()); + assertEquals("special", deluxe.getLocalName()); + assertEquals("a", deluxe.getPrefix()); + assertEquals("http://sales", deluxe.getNamespaceURI()); + } + + public void testUserDataHandlerNotifiedOfRenames() { + RecordingHandler handler = new RecordingHandler(); + description.setUserData("a", "apple", handler); + deluxe.setUserData("b", "banana", handler); + standard.setUserData("c", "cat", handler); + + document.renameNode(deluxe, null, "special"); + document.renameNode(description, null, "desc"); + + Set<String> expected = new HashSet<String>(); + expected.add(notification(NODE_RENAMED, "a", "apple", description, null)); + expected.add(notification(NODE_RENAMED, "b", "banana", deluxe, null)); + assertEquals(expected, handler.calls); + } + + public void testRenameToInvalid() { + try { + document.renameNode(description, null, "xmlns:foo"); + fail(); + } catch (DOMException e) { + } + try { + document.renameNode(description, null, "xml:foo"); + fail(); + } catch (DOMException e) { + } + try { + document.renameNode(deluxe, null, "xmlns"); + fail(); + } catch (DOMException e) { + } + } + + public void testRenameNodeOtherThanElementOrAttribute() { + for (Node node : allNodes) { + if (node.getNodeType() == Node.ATTRIBUTE_NODE + || node.getNodeType() == Node.ELEMENT_NODE) { + continue; + } + + try { + document.renameNode(node, null, "foo"); + fail(); + } catch (DOMException e) { + } + } + } + private class RecordingHandler implements UserDataHandler { final Set<String> calls = new HashSet<String>(); public void handle(short operation, String key, Object data, Node src, Node dst) { |