diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java index 6091a84f2a..73720a96ba 100644 --- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java +++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java @@ -32,6 +32,9 @@ import java.io.OutputStream; import java.io.FileDescriptor; +/* J2ObjC removed +import dalvik.annotation.optimization.ReachabilitySensitive; +*/ import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; import dalvik.system.SocketTagger; @@ -50,8 +53,8 @@ abstract class AbstractPlainSocketImpl extends SocketImpl { /* instance variable for SO_TIMEOUT */ int timeout; // timeout in millisec - // traffic class - int trafficClass; + // Android-removed: traffic class is set through socket. + // private int trafficClass; private boolean shut_rd = false; private boolean shut_wr = false; @@ -237,70 +240,78 @@ public void setOption(int opt, Object val) throws SocketException { if (isClosedOrPending()) { throw new SocketException("Socket Closed"); } + // BEGIN Android-removed: Logic dealing with value type moved to socketSetOption. + /* boolean on = true; switch (opt) { /* check type safety b4 going native. These should never * fail, since only java.Socket* has access to * PlainSocketImpl.setOption(). - */ - case SO_LINGER: - if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean))) - throw new SocketException("Bad parameter for option"); - if (val instanceof Boolean) { - /* true only if disabling - enabling should be Integer */ - on = false; - } - break; - case SO_TIMEOUT: - if (val == null || (!(val instanceof Integer))) - throw new SocketException("Bad parameter for SO_TIMEOUT"); - int tmp = ((Integer) val).intValue(); - if (tmp < 0) - throw new IllegalArgumentException("timeout < 0"); - timeout = tmp; - break; - case IP_TOS: - if (val == null || !(val instanceof Integer)) { - throw new SocketException("bad argument for IP_TOS"); - } - trafficClass = ((Integer)val).intValue(); - break; - case SO_BINDADDR: - throw new SocketException("Cannot re-bind socket"); - case TCP_NODELAY: - if (val == null || !(val instanceof Boolean)) - throw new SocketException("bad parameter for TCP_NODELAY"); - on = ((Boolean)val).booleanValue(); - break; - case SO_SNDBUF: - case SO_RCVBUF: - if (val == null || !(val instanceof Integer) || - !(((Integer)val).intValue() > 0)) { - throw new SocketException("bad parameter for SO_SNDBUF " + - "or SO_RCVBUF"); - } - break; - case SO_KEEPALIVE: - if (val == null || !(val instanceof Boolean)) - throw new SocketException("bad parameter for SO_KEEPALIVE"); - on = ((Boolean)val).booleanValue(); - break; - case SO_OOBINLINE: - if (val == null || !(val instanceof Boolean)) - throw new SocketException("bad parameter for SO_OOBINLINE"); - on = ((Boolean)val).booleanValue(); - break; - case SO_REUSEADDR: - if (val == null || !(val instanceof Boolean)) - throw new SocketException("bad parameter for SO_REUSEADDR"); - on = ((Boolean)val).booleanValue(); - break; - default: - throw new SocketException("unrecognized TCP option: " + opt); + * + case SO_LINGER: + if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean))) + throw new SocketException("Bad parameter for option"); + if (val instanceof Boolean) { + /* true only if disabling - enabling should be Integer * + on = false; + } + break; + case SO_TIMEOUT: + if (val == null || (!(val instanceof Integer))) + throw new SocketException("Bad parameter for SO_TIMEOUT"); + int tmp = ((Integer) val).intValue(); + if (tmp < 0) + throw new IllegalArgumentException("timeout < 0"); + timeout = tmp; + break; + case IP_TOS: + if (val == null || !(val instanceof Integer)) { + throw new SocketException("bad argument for IP_TOS"); + } + trafficClass = ((Integer)val).intValue(); + break; + case SO_BINDADDR: + throw new SocketException("Cannot re-bind socket"); + case TCP_NODELAY: + if (val == null || !(val instanceof Boolean)) + throw new SocketException("bad parameter for TCP_NODELAY"); + on = ((Boolean)val).booleanValue(); + break; + case SO_SNDBUF: + case SO_RCVBUF: + if (val == null || !(val instanceof Integer) || + !(((Integer)val).intValue() > 0)) { + throw new SocketException("bad parameter for SO_SNDBUF " + + "or SO_RCVBUF"); + } + break; + case SO_KEEPALIVE: + if (val == null || !(val instanceof Boolean)) + throw new SocketException("bad parameter for SO_KEEPALIVE"); + on = ((Boolean)val).booleanValue(); + break; + case SO_OOBINLINE: + if (val == null || !(val instanceof Boolean)) + throw new SocketException("bad parameter for SO_OOBINLINE"); + on = ((Boolean)val).booleanValue(); + break; + case SO_REUSEADDR: + if (val == null || !(val instanceof Boolean)) + throw new SocketException("bad parameter for SO_REUSEADDR"); + on = ((Boolean)val).booleanValue(); + break; + default: + throw new SocketException("unrecognized TCP option: " + opt); } socketSetOption(opt, on, val); + */ + // END Android-removed: Logic dealing with value type moved to socketSetOption. + // Android-added: Keep track of timeout value not handled by socketSetOption. + if (opt == SO_TIMEOUT) { + timeout = (Integer) val; + } + socketSetOption(opt, val); } - public Object getOption(int opt) throws SocketException { if (isClosedOrPending()) { throw new SocketException("Socket Closed"); @@ -308,6 +319,8 @@ public Object getOption(int opt) throws SocketException { if (opt == SO_TIMEOUT) { return new Integer(timeout); } + // BEGIN Android-changed: Logic dealing with value type moved to socketGetOption. + /* int ret = 0; /* * The native socketGetOption() knows about 3 options. @@ -315,43 +328,51 @@ public Object getOption(int opt) throws SocketException { * to what we're asking. A return of -1 means it understands * the option but its turned off. It will raise a SocketException * if "opt" isn't one it understands. - */ + * switch (opt) { - case TCP_NODELAY: - ret = socketGetOption(opt, null); - return Boolean.valueOf(ret != -1); - case SO_OOBINLINE: - ret = socketGetOption(opt, null); - return Boolean.valueOf(ret != -1); - case SO_LINGER: - ret = socketGetOption(opt, null); - return (ret == -1) ? Boolean.FALSE: (Object)(new Integer(ret)); - case SO_REUSEADDR: - ret = socketGetOption(opt, null); - return Boolean.valueOf(ret != -1); - case SO_BINDADDR: - InetAddressContainer in = new InetAddressContainer(); - ret = socketGetOption(opt, in); - return in.addr; - case SO_SNDBUF: - case SO_RCVBUF: - ret = socketGetOption(opt, null); - return new Integer(ret); - case IP_TOS: + case TCP_NODELAY: + ret = socketGetOption(opt, null); + return Boolean.valueOf(ret != -1); + case SO_OOBINLINE: + ret = socketGetOption(opt, null); + return Boolean.valueOf(ret != -1); + case SO_LINGER: + ret = socketGetOption(opt, null); + return (ret == -1) ? Boolean.FALSE: (Object)(new Integer(ret)); + case SO_REUSEADDR: + ret = socketGetOption(opt, null); + return Boolean.valueOf(ret != -1); + case SO_BINDADDR: + InetAddressContainer in = new InetAddressContainer(); + ret = socketGetOption(opt, in); + return in.addr; + case SO_SNDBUF: + case SO_RCVBUF: + ret = socketGetOption(opt, null); + return new Integer(ret); + case IP_TOS: + try { ret = socketGetOption(opt, null); if (ret == -1) { // ipv6 tos - return new Integer(trafficClass); + return trafficClass; } else { - return new Integer(ret); + return ret; } - case SO_KEEPALIVE: - ret = socketGetOption(opt, null); - return Boolean.valueOf(ret != -1); - // should never get here - default: - return null; + } catch (SocketException se) { + // TODO - should make better effort to read TOS or TCLASS + return trafficClass; // ipv6 tos + } + case SO_KEEPALIVE: + ret = socketGetOption(opt, null); + return Boolean.valueOf(ret != -1); + // should never get here + default: + return null; } + */ + return socketGetOption(opt); + // END Android-changed: Logic dealing with value type moved to socketGetOption. } /** @@ -542,12 +563,44 @@ protected void close() throws IOException { if (!stream) { ResourceManager.afterUdpClose(); } - if (closePending) { - return; + // Android-changed: Socket should be untagged before the preclose. + // After preclose, socket will dup2-ed to marker_fd, therefore, it won't describe + // the same file. If closingPending is true, then the socket has been preclosed. + // + // Also, close the CloseGuard when the #close is called. + if (!closePending) { + closePending = true; + guard.close(); + + if (fdUseCount == 0) { + /* + * We close the FileDescriptor in two-steps - first the + * "pre-close" which closes the socket but doesn't + * release the underlying file descriptor. This operation + * may be lengthy due to untransmitted data and a long + * linger interval. Once the pre-close is done we do the + * actual socket to release the fd. + */ + try { + socketPreClose(); + } finally { + socketClose(); + } + // Android-changed: Closed sockets use an invalid fd, not null. b/26470377 + // socketClose invalidates the fd by closing the fd. + // fd = null; + return; + } else { + /* + * If a thread has acquired the fd and a close + * isn't pending then use a deferred close. + * Also decrement fdUseCount to signal the last + * thread that releases the fd to close it. + */ + fdUseCount--; + socketPreClose(); + } } - closePending = true; - socketClose(); - return; } } } @@ -701,40 +754,45 @@ public int getTimeout() { return timeout; } + /* + * "Pre-close" a socket by dup'ing the file descriptor - this enables + * the socket to be closed without releasing the file descriptor. + */ + private void socketPreClose() throws IOException { + socketClose0(true); + } + /* * Close the socket (and release the file descriptor). */ protected void socketClose() throws IOException { - guard.close(); - - socketClose0(); + socketClose0(false); } abstract void socketCreate(boolean isServer) throws IOException; abstract void socketConnect(InetAddress address, int port, int timeout) - throws IOException; + throws IOException; abstract void socketBind(InetAddress address, int port) - throws IOException; + throws IOException; abstract void socketListen(int count) - throws IOException; + throws IOException; abstract void socketAccept(SocketImpl s) - throws IOException; + throws IOException; abstract int socketAvailable() - throws IOException; - abstract void socketClose0() - throws IOException; + throws IOException; + abstract void socketClose0(boolean useDeferredClose) + throws IOException; abstract void socketShutdown(int howto) - throws IOException; - abstract void socketSetOption(int cmd, boolean on, Object value) - throws SocketException; - abstract int socketGetOption(int opt, Object iaContainerObj) throws SocketException; + throws IOException; + + // Android-changed: Method signature changes. + // socket{Get,Set}Option work directly with Object values. + abstract void socketSetOption(int cmd, Object value) throws SocketException; + abstract Object socketGetOption(int opt) throws SocketException; + abstract void socketSendUrgentData(int data) - throws IOException; + throws IOException; public final static int SHUT_RD = 0; public final static int SHUT_WR = 1; } - -class InetAddressContainer { - InetAddress addr; -} \ No newline at end of file diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/BindException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/BindException.java index 9c2bb4830d..48c7106ec7 100644 --- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/BindException.java +++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/BindException.java @@ -31,7 +31,7 @@ * socket to a local address and port. Typically, the port is * in use, or the requested local address could not be assigned. * - * @since JDK1.1 + * @since 1.1 */ public class BindException extends SocketException { diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ConnectException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ConnectException.java index ff58643187..e67894e698 100644 --- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ConnectException.java +++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ConnectException.java @@ -32,7 +32,7 @@ * was refused remotely (e.g., no process is listening on the * remote address/port). * - * @since JDK1.1 + * @since 1.1 */ public class ConnectException extends SocketException { private static final long serialVersionUID = 3831404271622369215L; diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ContentHandlerFactory.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ContentHandlerFactory.java index 64112e3a80..994e266240 100644 --- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ContentHandlerFactory.java +++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ContentHandlerFactory.java @@ -36,15 +36,16 @@ * @author James Gosling * @see java.net.ContentHandler * @see java.net.URLStreamHandler - * @since JDK1.0 + * @since 1.0 */ public interface ContentHandlerFactory { + /** * Creates a new {@code ContentHandler} to read an object from * a {@code URLStreamHandler}. * * @param mimetype the MIME type for which a content handler is desired. - + * * @return a new {@code ContentHandler} to read an object from a * {@code URLStreamHandler}. * @see java.net.ContentHandler diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieHandler.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieHandler.java index 0d01256065..92fc9959b4 100644 --- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieHandler.java +++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieHandler.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.List; import java.io.IOException; +import sun.security.util.SecurityConstants; /** * A CookieHandler object provides a callback mechanism to hook up a @@ -35,9 +36,9 @@ * handler. The HTTP state management mechanism specifies a way to * create a stateful session with HTTP requests and responses. * - *
A system-wide CookieHandler that to used by the HTTP protocol - * handler can be registered by doing a - * CookieHandler.setDefault(CookieHandler). The currently registered + *
A system-wide CookieHandler to be used by the {@linkplain + * HttpURLConnection HTTP URL stream protocol handler} can be registered by + * doing a CookieHandler.setDefault(CookieHandler). The currently registered * CookieHandler can be retrieved by calling * CookieHandler.getDefault(). * diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieManager.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieManager.java index bff9734cca..e35a271cd0 100644 --- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieManager.java +++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/CookieManager.java @@ -82,7 +82,7 @@ *
+ *
* @param address The remote address.
* @param port The remote port
* @throws SocketException if binding the socket fails.
@@ -315,7 +317,7 @@ public DatagramSocket(int port) throws SocketException {
* {@code checkListen} method doesn't allow the operation.
*
* @see SecurityManager#checkListen
- * @since JDK1.1
+ * @since 1.1
*/
public DatagramSocket(int port, InetAddress laddr) throws SocketException {
this(new InetSocketAddress(laddr, port));
@@ -329,7 +331,7 @@ private void checkOldImpl() {
try {
/* J2ObjC removed.
AccessController.doPrivileged(
- new PrivilegedExceptionAction
* If the address is {@code null}, then the system will pick up
* an ephemeral port and a valid local address to bind the socket.
- *
+ *
* @param addr The address and port to bind to.
* @throws SocketException if any error happens during the bind, or if the
* socket is already bound.
@@ -496,7 +498,7 @@ public void connect(InetAddress address, int port) {
*
* If given an {@link InetSocketAddress InetSocketAddress}, this method
* behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
- * with the the given socket addresses IP address and port number.
+ * with the given socket addresses IP address and port number.
*
* @param addr The remote address.
*
@@ -935,13 +937,13 @@ public int getLocalPort() {
*
* @param timeout the specified timeout in milliseconds.
* @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
- * @since JDK1.1
+ * @since 1.1
* @see #getSoTimeout()
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
if (isClosed())
throw new SocketException("Socket is closed");
- getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+ getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
}
/**
@@ -950,7 +952,7 @@ public synchronized void setSoTimeout(int timeout) throws SocketException {
*
* @return the setting for SO_TIMEOUT
* @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
- * @since JDK1.1
+ * @since 1.1
* @see #setSoTimeout(int)
*/
public synchronized int getSoTimeout() throws SocketException {
@@ -1003,7 +1005,7 @@ public synchronized void setSendBufferSize(int size)
}
if (isClosed())
throw new SocketException("Socket is closed");
- getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
+ getImpl().setOption(SocketOptions.SO_SNDBUF, size);
}
/**
@@ -1028,7 +1030,7 @@ public synchronized int getSendBufferSize() throws SocketException {
/**
* Sets the SO_RCVBUF option to the specified value for this
- * {@code DatagramSocket}. The SO_RCVBUF option is used by the
+ * {@code DatagramSocket}. The SO_RCVBUF option is used by
* the network implementation as a hint to size the underlying
* network I/O buffers. The SO_RCVBUF setting may also be used
* by the network implementation to determine the maximum size
@@ -1061,7 +1063,7 @@ public synchronized void setReceiveBufferSize(int size)
}
if (isClosed())
throw new SocketException("Socket is closed");
- getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+ getImpl().setOption(SocketOptions.SO_RCVBUF, size);
}
/**
@@ -1123,7 +1125,7 @@ public synchronized void setReuseAddress(boolean on) throws SocketException {
throw new SocketException("Socket is closed");
// Integer instead of Boolean for compatibility with older DatagramSocketImpl
if (oldImpl)
- getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer(on?-1:0));
+ getImpl().setOption(SocketOptions.SO_REUSEADDR, on?-1:0);
else
getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
}
@@ -1333,10 +1335,8 @@ public DatagramChannel getChannel() {
* datagram socket factory.
* @exception SocketException if the factory is already defined.
* @exception SecurityException if a security manager exists and its
- * {@code checkSetFactory} method doesn't allow the
- operation.
- * @see
- java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
+ * {@code checkSetFactory} method doesn't allow the operation.
+ * @see java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
* @see SecurityManager#checkSetFactory
* @since 1.3
*/
@@ -1354,12 +1354,107 @@ public DatagramChannel getChannel() {
factory = fac;
}
+ /**
+ * Sets the value of a socket option.
+ *
+ * @param Internationalized domain names are defined in RFC 3490.
+ * RFC 3490 defines two operations: ToASCII and ToUnicode. These 2 operations employ
+ * Nameprep algorithm, which is a
+ * profile of Stringprep, and
+ * Punycode algorithm to convert
+ * domain name string back and forth.
+ *
+ * The behavior of aforementioned conversion process can be adjusted by various flags:
+ * See RFC 3490 for full details.
+ * The security consideration is important with respect to internationalization
+ * domain name support. For example, English domain names may be homographed
+ * - maliciously misspelled by substitution of non-Latin letters.
+ * Unicode Technical Report #36
+ * discusses security issues of IDN support as well as possible solutions.
+ * Applications are responsible for taking adequate security measures when using
+ * international domain names.
*
+ * @author Edward Wang
* @since 1.6
+ *
*/
public final class IDN {
/**
- * When set, allows IDN to process unassigned unicode points.
+ * Flag to allow processing of unassigned code points
*/
- public static final int ALLOW_UNASSIGNED = 1;
+ public static final int ALLOW_UNASSIGNED = 0x01;
/**
- * When set, ASCII strings are checked against
- * RFC 1122 and
- * RFC 1123.
+ * Flag to turn on the check against STD-3 ASCII rules
*/
- public static final int USE_STD3_ASCII_RULES = 2;
+ public static final int USE_STD3_ASCII_RULES = 0x02;
- private IDN() {
- }
/**
- * Transform a Unicode String to ASCII Compatible Encoding String according
- * to the algorithm defined in RFC 3490.
- *
- * If the transformation fails (because the input is not a valid IDN), an
- * exception will be thrown.
- *
- * This method can handle either an individual label or an entire domain name.
- * In the latter case, the separators are: U+002E (full stop), U+3002 (ideographic full stop),
- * U+FF0E (fullwidth full stop), and U+FF61 (halfwidth ideographic full stop).
- * All of these will become U+002E (full stop) in the result.
- *
- * @param input the Unicode name
- * @param flags 0, {@code ALLOW_UNASSIGNED}, {@code USE_STD3_ASCII_RULES},
- * or {@code ALLOW_UNASSIGNED | USE_STD3_ASCII_RULES}
- * @return the ACE name
- * @throws IllegalArgumentException if {@code input} does not conform to RFC 3490
+ * Translates a string from Unicode to ASCII Compatible Encoding (ACE),
+ * as defined by the ToASCII operation of RFC 3490.
+ *
+ * ToASCII operation can fail. ToASCII fails if any step of it fails.
+ * If ToASCII operation fails, an IllegalArgumentException will be thrown.
+ * In this case, the input string should not be used in an internationalized domain name.
+ *
+ * A label is an individual part of a domain name. The original ToASCII operation,
+ * as defined in RFC 3490, only operates on a single label. This method can handle
+ * both label and entire domain name, by assuming that labels in a domain name are
+ * always separated by dots. The following characters are recognized as dots:
+ * \u002E (full stop), \u3002 (ideographic full stop), \uFF0E (fullwidth full stop),
+ * and \uFF61 (halfwidth ideographic full stop). if dots are
+ * used as label separators, this method also changes all of them to \u002E (full stop)
+ * in output translated string.
+ *
+ * @param input the string to be processed
+ * @param flag process flag; can be 0 or any logical OR of possible flags
+ *
+ * @return the translated {@code String}
+ *
+ * @throws IllegalArgumentException if the input string doesn't conform to RFC 3490 specification
*/
- public static String toASCII(String input, int flags) {
- return NativeIDN.toASCII(input, flags);
+ public static String toASCII(String input, int flag) {
+ return NativeIDN.toASCII(input, flag);
+ /* J2ObjC modified
+ // BEGIN Android-changed: Use ICU4J implementation.
+ try {
+ return NativeIDN.toASCII(input, flag);
+ } catch (android.icu.text.StringPrepParseException e) {
+ // b/113787610: "." is a valid IDN but is rejected by ICU.
+ // Usage is relatively uncommon, so only check for it if ICU throws.
+ if (".".equals(input)) {
+ return input;
+ }
+ throw new IllegalArgumentException("Invalid input to toASCII: " + input, e);
+ }
+ // END Android-changed: Use ICU4J implementation.
+ */
}
+
/**
- * Equivalent to {@code toASCII(input, 0)}.
+ * Translates a string from Unicode to ASCII Compatible Encoding (ACE),
+ * as defined by the ToASCII operation of RFC 3490.
+ *
+ * This convenience method works as if by invoking the
+ * two-argument counterpart as follows:
+ * ToUnicode never fails. In case of any error, the input string is returned unmodified.
*
- * Unlike {@code toASCII}, this transformation cannot fail.
+ * A label is an individual part of a domain name. The original ToUnicode operation,
+ * as defined in RFC 3490, only operates on a single label. This method can handle
+ * both label and entire domain name, by assuming that labels in a domain name are
+ * always separated by dots. The following characters are recognized as dots:
+ * \u002E (full stop), \u3002 (ideographic full stop), \uFF0E (fullwidth full stop),
+ * and \uFF61 (halfwidth ideographic full stop).
*
- * This method can handle either an individual label or an entire domain name.
- * In the latter case, the separators are: U+002E (full stop), U+3002 (ideographic full stop),
- * U+FF0E (fullwidth full stop), and U+FF61 (halfwidth ideographic full stop).
+ * @param input the string to be processed
+ * @param flag process flag; can be 0 or any logical OR of possible flags
*
- * @param input the ACE name
- * @return the Unicode name
- * @param flags 0, {@code ALLOW_UNASSIGNED}, {@code USE_STD3_ASCII_RULES},
- * or {@code ALLOW_UNASSIGNED | USE_STD3_ASCII_RULES}
+ * @return the translated {@code String}
*/
- public static String toUnicode(String input, int flags) {
- return NativeIDN.toUnicode(input, flags);
+ public static String toUnicode(String input, int flag) {
+ return NativeIDN.toUnicode(input, flag);
+ /* J2ObjC modified
+ // BEGIN Android-changed: Use ICU4J implementation.
+ try {
+ // ICU only translates separators to ASCII for toASCII.
+ // Java expects the translation for toUnicode too.
+ return convertFullStop(ExtendedIDNA.convertIDNToUnicode(input, flag)).toString();
+ } catch (android.icu.text.StringPrepParseException e) {
+ // The RI documentation explicitly states that if the conversion was unsuccessful
+ // the original string is returned.
+ return input;
+ }
+ // END Android-changed: Use ICU4J implementation.
+ */
+ }
+
+ /* J2ObjC removed
+ // BEGIN Android-added: Use ICU4J implementation.
+ private static boolean isLabelSeperator(char c) {
+ return (c == '\u3002' || c == '\uff0e' || c == '\uff61');
}
+ private static StringBuffer convertFullStop(StringBuffer input) {
+ for (int i = 0; i < input.length(); i++) {
+ if (isLabelSeperator(input.charAt(i))) {
+ input.setCharAt(i, '.');
+ }
+ }
+ return input;
+ }
+ // END Android-added: Use ICU4J implementation.
+ */
+
/**
- * Equivalent to {@code toUnicode(input, 0)}.
+ * Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
+ * as defined by the ToUnicode operation of RFC 3490.
+ *
+ * This convenience method works as if by invoking the
+ * two-argument counterpart as follows:
+ * When four parts are specified, each is interpreted as a byte of
* data and assigned, from left to right, to the four bytes of an IPv4
@@ -86,7 +86,7 @@
public final
class Inet4Address extends InetAddress {
- final static int INADDRSZ = 4;
+ static final int INADDRSZ = 4;
/** use serialVersionUID from InetAddress, but Inet4Address instance
* is always replaced by an InetAddress instance before being
@@ -94,14 +94,27 @@ class Inet4Address extends InetAddress {
private static final long serialVersionUID = 3286316764910316507L;
// BEGIN Android-added: Define special-purpose IPv4 address.
- /** @hide */
+ /**
+ * Reserved address for {@code INADDR_ANY}, to specify any IPv4 address at all.
+ *
+ * @hide
+ */
public static final InetAddress ANY = new Inet4Address(null, new byte[] { 0, 0, 0, 0 });
- /** @hide */
+ /**
+ * Broadcast address to transmit to all devices on network.
+ *
+ * @hide
+ */
public static final InetAddress ALL =
new Inet4Address(null, new byte[] { (byte) 255, (byte) 255,
(byte) 255, (byte) 255 });
- /** @hide */
+
+ /**
+ * Loopback address to the local host.
+ *
+ * @hide
+ */
public static final InetAddress LOOPBACK =
new Inet4Address("localhost", new byte[] { 127, 0, 0, 1 });
// END Android-added: Define special-purpose IPv4 address.
@@ -175,17 +188,15 @@ private Object writeReplace() throws ObjectStreamException {
* address i.e first four bits of the address are 1110.
* @return a {@code boolean} indicating if the InetAddress is
* an IP multicast address
- * @since JDK1.1
*/
public boolean isMulticastAddress() {
return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
}
/**
- * Utility routine to check if the InetAddress in a wildcard address.
+ * Utility routine to check if the InetAddress is a wildcard address.
* @return a {@code boolean} indicating if the Inetaddress is
* a wildcard address.
- * @since 1.4
*/
public boolean isAnyLocalAddress() {
return holder().getAddress() == 0;
@@ -196,7 +207,6 @@ public boolean isAnyLocalAddress() {
*
* @return a {@code boolean} indicating if the InetAddress is
* a loopback address; or false otherwise.
- * @since 1.4
*/
public boolean isLoopbackAddress() {
/* 127.x.x.x */
@@ -209,7 +219,6 @@ public boolean isLoopbackAddress() {
*
* @return a {@code boolean} indicating if the InetAddress is
* a link local address; or false if address is not a link local unicast address.
- * @since 1.4
*/
public boolean isLinkLocalAddress() {
// link-local unicast in IPv4 (169.254.0.0/16)
@@ -226,7 +235,6 @@ public boolean isLinkLocalAddress() {
*
* @return a {@code boolean} indicating if the InetAddress is
* a site local address; or false if address is not a site local unicast address.
- * @since 1.4
*/
public boolean isSiteLocalAddress() {
// refer to RFC 1918
@@ -247,7 +255,6 @@ public boolean isSiteLocalAddress() {
* @return a {@code boolean} indicating if the address has
* is a multicast address of global scope, false if it is not
* of global scope or it is not a multicast address
- * @since 1.4
*/
public boolean isMCGlobal() {
// 224.0.1.0 to 238.255.255.255
@@ -263,7 +270,6 @@ public boolean isMCGlobal() {
* @return a {@code boolean} indicating if the address has
* is a multicast address of node-local scope, false if it is not
* of node-local scope or it is not a multicast address
- * @since 1.4
*/
public boolean isMCNodeLocal() {
// unless ttl == 0
@@ -276,7 +282,6 @@ public boolean isMCNodeLocal() {
* @return a {@code boolean} indicating if the address has
* is a multicast address of link-local scope, false if it is not
* of link-local scope or it is not a multicast address
- * @since 1.4
*/
public boolean isMCLinkLocal() {
// 224.0.0/24 prefix and ttl == 1
@@ -292,7 +297,6 @@ public boolean isMCLinkLocal() {
* @return a {@code boolean} indicating if the address has
* is a multicast address of site-local scope, false if it is not
* of site-local scope or it is not a multicast address
- * @since 1.4
*/
public boolean isMCSiteLocal() {
// 239.255/16 prefix or ttl < 32
@@ -308,7 +312,6 @@ public boolean isMCSiteLocal() {
* is a multicast address of organization-local scope,
* false if it is not of organization-local scope
* or it is not a multicast address
- * @since 1.4
*/
public boolean isMCOrgLocal() {
// 239.192 - 239.195
@@ -340,7 +343,6 @@ public byte[] getAddress() {
* Returns the IP address string in textual presentation form.
*
* @return the raw IP address in a string format.
- * @since JDK1.0.2
*/
public String getHostAddress() {
return numericToTextFormat(getAddress());
@@ -377,15 +379,13 @@ public boolean equals(Object obj) {
}
// Utilities
- /*
+
+ /**
* Converts IPv4 binary address into a string suitable for presentation.
*
* @param src a byte array representing an IPv4 numeric address
* @return a String representing the IPv4 address in
- * textual representation format
- * @since 1.4
*/
-
static String numericToTextFormat(byte[] src)
{
return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6Address.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6Address.java
index 6ea112742d..e1ba7d734f 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6Address.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6Address.java
@@ -26,17 +26,17 @@
package java.net;
+import static libcore.io.OsConstants.*;
+
import com.google.j2objc.annotations.Weak;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
-import java.util.Enumeration;
import java.util.Arrays;
-import libcore.io.Libcore;
+import java.util.Enumeration;
import libcore.io.NetworkOs;
-import static libcore.io.OsConstants.*;
/*-[
#include "JreRetainedWith.h"
@@ -184,22 +184,31 @@
class Inet6Address extends InetAddress {
final static int INADDRSZ = 16;
- // BEGIN Android-removed: Remove special handling for link-local addresses.
- /*
- * cached scope_id - for link-local address use only.
- *
- private transient int cached_scope_id; // 0
- */
- // END Android-removed: Remove special handling for link-local addresses.
-
- // BEGIN Android-added: Define special-purpose IPv6 address.
- /** @hide */
- public static final InetAddress ANY =
- new Inet6Address("::", new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0);
-
- /** @hide */
- public static final InetAddress LOOPBACK = new Inet6Address("ip6-localhost",
- new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 0);
+ // BEGIN Android-removed: Remove special handling for link-local addresses.
+ /*
+ * cached scope_id - for link-local address use only.
+ *
+ private transient int cached_scope_id; // 0
+ */
+ // END Android-removed: Remove special handling for link-local addresses.
+
+ // BEGIN Android-added: Define special-purpose IPv6 address.
+ /**
+ * Reserved address for {@code INADDR_ANY}, to specify any IPv6 address at all.
+ *
+ * @hide
+ */
+ public static final InetAddress ANY =
+ new Inet6Address("::", new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0);
+
+ /**
+ * Loopback address to the local host.
+ *
+ * @hide
+ */
+ public static final InetAddress LOOPBACK =
+ new Inet6Address(
+ "ip6-localhost", new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 0);
// END Android-added: Define special-purpose IPv6 address.
/* J2ObjC removed: private */ class Inet6AddressHolder {
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6AddressImpl.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6AddressImpl.java
index 66b8995bbc..964c47fc73 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6AddressImpl.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Inet6AddressImpl.java
@@ -44,6 +44,12 @@
import static libcore.io.OsConstants.ECONNREFUSED;
import static libcore.io.OsConstants.EPERM;
import static libcore.io.OsConstants.NI_NAMEREQD;
+/* J2ObjC removed
+import static libcore.io.OsConstants.ICMP6_ECHO_REPLY;
+import static libcore.io.OsConstants.ICMP_ECHOREPLY;
+import static libcore.io.OsConstants.IPPROTO_ICMP;
+import static libcore.io.OsConstants.IPPROTO_ICMPV6;
+*/
import static libcore.io.OsConstants.SOCK_DGRAM;
import static libcore.io.OsConstants.SOCK_STREAM;
@@ -201,19 +207,19 @@ public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif
}
// Android-changed: http://b/36933260 Implement root-less ICMP for isReachable().
- /*
- if (addr instanceof Inet6Address)
- scope = ((Inet6Address) addr).getScopeId();
- return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope);
+ /*
+ if (addr instanceof Inet6Address)
+ scope = ((Inet6Address) addr).getScopeId();
+ return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope);
*
// Try ICMP first
- if (icmpEcho(addr, timeout, sourceAddr, ttl)) {
+ if (icmpEcho(addr, timeout, sourceAddr, ttl)) {
return true;
}
// No good, let's fall back to TCP
- return tcpEcho(addr, timeout, sourceAddr, ttl);
- */
+ return tcpEcho(addr, timeout, sourceAddr, ttl);
+ */
byte[] ifaddr = null;
int scope = -1;
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetAddress.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetAddress.java
index 7856a0dd26..b7ce5ac1ee 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetAddress.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetAddress.java
@@ -1050,7 +1050,7 @@ public static InetAddress getByAddress(String host, byte[] addr) throws UnknownH
// Android-added: Called by native code in Libcore.io.
// Do not delete. Called from native code.
- public static InetAddress getByAddress(String host, byte[] addr, int scopeId)
+ private static InetAddress getByAddress(String host, byte[] addr, int scopeId)
throws UnknownHostException {
if (host != null && host.length() > 0 && host.charAt(0) == '[') {
if (host.charAt(host.length()-1) == ']') {
@@ -1678,7 +1678,7 @@ public static void clearDnsCache() {
* @param netId the network to use for host resolution.
* @return the {@code InetAddress} instance representing the host.
* @throws UnknownHostException if the address lookup fails.
- * @hide internal use only
+ * @hide
*/
public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
return impl.lookupAllHostAddr(host, netId)[0];
@@ -1692,7 +1692,7 @@ public static InetAddress getByNameOnNet(String host, int netId) throws UnknownH
* @param netId the network to use for host resolution.
* @return the array of addresses associated with the specified host.
* @throws UnknownHostException if the address lookup fails.
- * @hide internal use only
+ * @hide
*/
public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
return impl.lookupAllHostAddr(host, netId).clone();
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetSocketAddress.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetSocketAddress.java
index 74b559bcf7..9f53d147f2 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetSocketAddress.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/InetSocketAddress.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -168,7 +168,7 @@ public InetSocketAddress() {
* A valid port value is between 0 and 65535.
* A port number of {@code zero} will let the system pick up an
* ephemeral port in a {@code bind} operation.
- *
+ *
* @param port The port number
* @throws IllegalArgumentException if the port parameter is outside the specified
* range of valid port values.
@@ -188,7 +188,7 @@ public InetSocketAddress(int port) {
* ephemeral port in a {@code bind} operation.
*
* A {@code null} address will assign the wildcard address.
- *
+ *
* @param addr The IP address
* @param port The port number
* @throws IllegalArgumentException if the port parameter is outside the specified
@@ -217,11 +217,11 @@ public InetSocketAddress(InetAddress addr, int port) {
* A valid port value is between 0 and 65535.
* A port number of {@code zero} will let the system pick up an
* ephemeral port in a {@code bind} operation.
- *
+ *
* @param hostname the Host name
* @param port The port number
* @throws IllegalArgumentException if the port parameter is outside the range
- * of valid port values, or if the hostname parameter is null.
+ * of valid port values, or if the hostname parameter is {@code null}.
* @throws SecurityException if a security manager is present and
* permission to resolve the host name is
* denied.
@@ -254,14 +254,14 @@ private InetSocketAddress(int port, String hostname) {
* A valid port value is between 0 and 65535.
* A port number of {@code zero} will let the system pick up an
* ephemeral port in a {@code bind} operation.
- *
+ *
* @param host the Host name
* @param port The port number
* @throws IllegalArgumentException if the port parameter is outside
* the range of valid port values, or if the hostname
- * parameter is null.
+ * parameter is {@code null}.
* @see #isUnresolved()
- * @return a {@code InetSocketAddress} representing the unresolved
+ * @return an {@code InetSocketAddress} representing the unresolved
* socket address
* @since 1.5
*/
@@ -317,6 +317,13 @@ private void readObjectNoData()
throw new InvalidObjectException("Stream data required");
}
+ /* J2ObjC modified
+ private static final jdk.internal.misc.Unsafe UNSAFE
+ = jdk.internal.misc.Unsafe.getUnsafe();
+ private static final long FIELDS_OFFSET
+ = UNSAFE.objectFieldOffset(InetSocketAddress.class, "holder");
+ */
+
private static final long FIELDS_OFFSET;
private static final sun.misc.Unsafe UNSAFE;
static {
@@ -340,10 +347,9 @@ public final int getPort() {
}
/**
- *
* Gets the {@code InetAddress}.
*
- * @return the InetAdress or {@code null} if it is unresolved.
+ * @return the InetAddress or {@code null} if it is unresolved.
*/
public final InetAddress getAddress() {
return holder.getAddress();
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/JarURLConnection.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/JarURLConnection.java
index 70dedec795..c5acbf4b65 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/JarURLConnection.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/JarURLConnection.java
@@ -173,7 +173,18 @@ private void parseSpecs(URL url) throws MalformedURLException {
}
jarFileURL = new URL(spec.substring(0, separator++));
+
+ // Android-removed: runtime versioning is unsupported
+ /*
+ * The url argument may have had a runtime fragment appended, so
+ * we need to add a runtime fragment to the jarFileURL to enable
+ * runtime versioning when the underlying jar file is opened.
+ *
+ if ("runtime".equals(url.getRef())) {
+ jarFileURL = new URL(jarFileURL, "#runtime");
+ }
entryName = null;
+ */
/* if ! is the last letter of the innerURL, entryName is null */
if (++separator != spec.length()) {
@@ -246,7 +257,7 @@ public Manifest getManifest() throws IOException {
* @see #getJarEntry
*/
public JarEntry getJarEntry() throws IOException {
- return getJarFile().getJarEntry(entryName);
+ return entryName == null ? null : getJarFile().getJarEntry(entryName);
}
/**
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MalformedURLException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MalformedURLException.java
index 7aef75c782..5f9ab5111a 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MalformedURLException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MalformedURLException.java
@@ -33,7 +33,7 @@
* string could not be parsed.
*
* @author Arthur van Hoff
- * @since JDK1.0
+ * @since 1.0
*/
public class MalformedURLException extends IOException {
private static final long serialVersionUID = -182787522200415866L;
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MulticastSocket.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MulticastSocket.java
index 83a18c3a3d..5b5863f984 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MulticastSocket.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/MulticastSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,9 @@
package java.net;
import java.io.IOException;
+import java.util.Collections;
import java.util.Enumeration;
+import java.util.Set;
// Android-changed: Updated example code to handle non-ASCII characters
/**
@@ -79,7 +81,7 @@
* Currently applets are not allowed to use multicast sockets.
*
* @author Pavani Diwanji
- * @since JDK1.1
+ * @since 1.1
*/
public
class MulticastSocket extends DatagramSocket {
@@ -93,21 +95,22 @@ class MulticastSocket extends DatagramSocket {
/**
* Create a multicast socket.
*
- * If there is a security manager,
- * its {@code checkListen} method is first called
- * with 0 as its argument to ensure the operation is allowed.
- * This could result in a SecurityException.
+ *
+ * If there is a security manager, its {@code checkListen} method is first
+ * called with 0 as its argument to ensure the operation is allowed. This
+ * could result in a SecurityException.
*
* When the socket is created the
- * {@link DatagramSocket#setReuseAddress(boolean)} method is
- * called to enable the SO_REUSEADDR socket option.
+ * {@link DatagramSocket#setReuseAddress(boolean)} method is called to
+ * enable the SO_REUSEADDR socket option.
*
- * @exception IOException if an I/O exception occurs
- * while creating the MulticastSocket
- * @exception SecurityException if a security manager exists and its
- * {@code checkListen} method doesn't allow the operation.
+ * @exception IOException if an I/O exception occurs while creating the
+ * MulticastSocket
+ * @exception SecurityException if a security manager exists and its
+ * {@code checkListen} method doesn't allow the operation.
* @see SecurityManager#checkListen
* @see java.net.DatagramSocket#setReuseAddress(boolean)
+ * @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)
*/
public MulticastSocket() throws IOException {
this(new InetSocketAddress(0));
@@ -173,8 +176,9 @@ public MulticastSocket(SocketAddress bindaddr) throws IOException {
try {
bind(bindaddr);
} finally {
- if (!isBound())
+ if (!isBound()) {
close();
+ }
}
}
}
@@ -290,8 +294,9 @@ public int getTimeToLive() throws IOException {
*
* @param mcastaddr is the multicast address to join
*
- * @exception IOException if there is an error joining
- * or when the address is not a multicast address.
+ * @exception IOException if there is an error joining, or when the address
+ * is not a multicast address, or the platform does not support
+ * multicasting
* @exception SecurityException if a security manager exists and its
* {@code checkMulticast} method doesn't allow the join.
*
@@ -374,8 +379,9 @@ public void leaveGroup(InetAddress mcastaddr) throws IOException {
* {@link MulticastSocket#setInterface(InetAddress)} or
* {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
*
- * @exception IOException if there is an error joining
- * or when the address is not a multicast address.
+ * @exception IOException if there is an error joining, or when the address
+ * is not a multicast address, or the platform does not support
+ * multicasting
* @exception SecurityException if a security manager exists and its
* {@code checkMulticast} method doesn't allow the join.
* @throws IllegalArgumentException if mcastaddr is null or is a
@@ -709,4 +715,24 @@ public void send(DatagramPacket p, byte ttl)
} // synch p
} //synch ttl
} //method
+
+ private static Set
* Note that information about
* {@link NetworkInterface}s may be restricted. For example, non-system apps
- * with {@code targetSdkVersion >= android.internal.Build.VERSION_CODES.R} will only
- * have access to information about {@link NetworkInterface}s that are
+ * will only have access to information about {@link NetworkInterface}s that are
* associated with an {@link InetAddress}.
*
* @since 1.4
*/
public final class NetworkInterface {
+ // Android-added: Anonymized address for apps targeting old API versions. http://b/170188668
+ /**
+ * If this change is enabled, {@link #getHardwareAddress()} returns null when the hardware
+ * address is inaccessible. If the change is disabled, the
+ * default MAC address (02:00:00:00:00:00) is returned instead.
+ *
+ * @hide
+ */
+ /* J2ObjC removed
+ @ChangeId
+ @EnabledSince(targetSdkVersion=VersionCodes.R)
+ */
+ public static final long RETURN_NULL_HARDWARE_ADDRESS = 170188668L;
+ // The default hardware address is a zeroed-out MAC address with only its
+ // locally-administered bit set, returned to apps targeting older API versions if they would
+ // otherwise see a null MAC address.
+ // Matches android.net.wifi.WifiInfo.DEFAULT_MAC_ADDRESS
+ private static final byte[] DEFAULT_MAC_ADDRESS = {
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
private String name;
private String displayName;
private int index;
@@ -275,7 +298,7 @@ public String getDisplayName() {
return "".equals(displayName) ? null : displayName;
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Document restrictions for non-system apps. http://b/170188668
/**
* Searches for the network interface with the specified name.
*
@@ -310,7 +333,7 @@ public static NetworkInterface getByName(String name) throws SocketException {
return getByName0(name);
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Document restrictions for non-system apps. http://b/170188668
/**
* Get a network interface given its index.
*
@@ -385,7 +408,8 @@ public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketE
return getByInetAddress0(addr);
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Document restrictions for non-system apps. http://b/170188668
+ // Android-added: Note about NullPointerException in older versions. http://b/206053582
/**
* Returns all the interfaces on this machine. The {@code Enumeration}
* contains at least one element, possibly representing a loopback
@@ -395,10 +419,12 @@ public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketE
* NOTE: can use getNetworkInterfaces()+getInetAddresses()
* to obtain all IP addresses for this node
*
- * For non-system apps with
- * {@code targetSdkVersion >= android.internal.Build.VERSION_CODES.R}, this
- * method will only return information for {@link NetworkInterface}s that
- * are associated with an {@link InetAddress}.
+ * For non-system apps, this method will only return information for
+ * {@link NetworkInterface}s associated with an {@link InetAddress}.
+ *
+ * ANDROID NOTE: On Android versions before S (API level 31), this method may throw a
+ * NullPointerException if called in an environment where there is a virtual
+ * interface without a parent interface present.
*
* @return an Enumeration of NetworkInterfaces found on this machine
* that are accessible.
@@ -446,6 +472,10 @@ private static NetworkInterface[] getAll() throws SocketException {
StructIfaddrs[] ifaddrs;
try {
ifaddrs = Libcore.os.getifaddrs();
+ // Defensive check for b/217749090: ifaddrs should never be null.
+ if (ifaddrs == null) {
+ throw new SocketException("Failed to query network interfaces.");
+ }
} catch (ErrnoException e) {
throw e.rethrowAsSocketException();
}
@@ -507,8 +537,11 @@ private static NetworkInterface[] getAll() throws SocketException {
NetworkInterface parent = nis.get(parentName);
ni.virtual = true;
- ni.parent = parent;
- parent.childs.add(ni);
+
+ if (parent != null) {
+ ni.parent = parent;
+ parent.childs.add(ni);
+ }
}
}
@@ -599,7 +632,7 @@ public boolean supportsMulticast() throws SocketException {
return supportsMulticast0(name, index);
}
- // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+ // Android-added: Restrictions for non-system apps. http://b/170188668
/**
* Returns the hardware address (usually MAC) of the interface if it
* has one and if it can be accessed given the current privileges.
@@ -611,8 +644,8 @@ public boolean supportsMulticast() throws SocketException {
* manager is set and the caller does not have the permission
* NetPermission("getNetworkInformation"). For example, this
* method will generally return {@code null} when called by
- * non-system apps having
- * {@code targetSdkVersion >= android.internal.Build.VERSION_CODES.R}.
+ * non-system apps (or 02:00:00:00:00:00 for apps having
+ * {@code targetSdkVersion < android.os.Build.VERSION_CODES.R}).
*
* @exception SocketException if an I/O error occurs.
* @since 1.6
@@ -631,6 +664,15 @@ public byte[] getHardwareAddress() throws SocketException {
if (ni == null) {
throw new SocketException("NetworkInterface doesn't exist anymore");
}
+
+ /* J2ObjC removed
+ // Return 02:00:00:00:00:00 for apps having a target SDK version < R if they would have
+ // otherwise gotten a null MAC address (excluding loopback).
+ if (ni.hardwareAddr == null && !"lo".equals(name)
+ && !Compatibility.isChangeEnabled(RETURN_NULL_HARDWARE_ADDRESS)) {
+ return DEFAULT_MAC_ADDRESS.clone();
+ }
+ */
return ni.hardwareAddr;
// END Android-changed: Fix upstream not returning link-down interfaces. http://b/26238832
}
@@ -684,6 +726,7 @@ public boolean isVirtual() {
private native static boolean isLoopback0(String name, int ind) throws SocketException;
private native static boolean supportsMulticast0(String name, int ind) throws SocketException;
private native static boolean isP2P0(String name, int ind) throws SocketException;
+ private native static byte[] getMacAddr0(byte[] inAddr, String name, int ind) throws SocketException;
private native static int getMTU0(String name, int ind) throws SocketException;
/* J2ObjC removed: use native methods instead.
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/NoRouteToHostException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/NoRouteToHostException.java
index 76f0814cb4..cf6e68cfa5 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/NoRouteToHostException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/NoRouteToHostException.java
@@ -31,7 +31,7 @@
* host cannot be reached because of an intervening firewall, or
* if an intermediate router is down.
*
- * @since JDK1.1
+ * @since 1.1
*/
public class NoRouteToHostException extends SocketException {
private static final long serialVersionUID = -1897550894873493790L;
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
index cd00b0bd88..ef776f779f 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007,2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,32 @@
import java.io.IOException;
+/* J2ObjC removed
+import android.system.ErrnoException;
+import android.system.StructGroupReq;
+
+
+import libcore.io.IoBridge;
+import libcore.io.Libcore;
+import libcore.util.EmptyArray;
+
+import jdk.net.*;
+
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNSPEC;
+import static android.system.OsConstants.IPPROTO_IP;
+import static android.system.OsConstants.IP_MULTICAST_ALL;
+import static android.system.OsConstants.MSG_PEEK;
+import static android.system.OsConstants.POLLERR;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static libcore.io.IoBridge.JAVA_IP_MULTICAST_TTL;
+import static libcore.io.IoBridge.JAVA_MCAST_JOIN_GROUP;
+import static libcore.io.IoBridge.JAVA_MCAST_LEAVE_GROUP;
+import static sun.net.ExtendedOptionsImpl.*;
+*/
+
+// Android-changed: Rewritten to use android.system POSIX calls and assume AF_INET6.
/*
* On Unix systems we simply delegate to native methods.
*
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainSocketImpl.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainSocketImpl.java
index 0734662f3b..ce4d6a6355 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainSocketImpl.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/PlainSocketImpl.java
@@ -37,23 +37,27 @@
class PlainSocketImpl extends AbstractPlainSocketImpl
{
static {
- initProto();
+ initProto();
}
/**
* Constructs an empty instance.
*/
PlainSocketImpl() {
- this(new FileDescriptor());
+ // Android-changed: Let PlainSocketImpl construct its own FileDescriptor.
+ this.fd = new FileDescriptor();
}
/**
* Constructs an instance with the given file descriptor.
*/
+ // Android-removed: Let PlainSocketImpl construct its own FileDescriptor.
+ // J2ObjC modified
PlainSocketImpl(FileDescriptor fd) {
this.fd = fd;
}
+
private static native void initProto();
native void socketCreate(boolean isServer) throws IOException;
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ProtocolException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ProtocolException.java
index 594428255c..31d044927b 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ProtocolException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ProtocolException.java
@@ -33,7 +33,7 @@
* protocol, such as a TCP error.
*
* @author Chris Warth
- * @since JDK1.0
+ * @since 1.0
*/
public
class ProtocolException extends IOException {
@@ -43,10 +43,10 @@ class ProtocolException extends IOException {
* Constructs a new {@code ProtocolException} with the
* specified detail message.
*
- * @param host the detail message.
+ * @param message the detail message.
*/
- public ProtocolException(String host) {
- super(host);
+ public ProtocolException(String message) {
+ super(message);
}
/**
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Proxy.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Proxy.java
index 8ba020ef48..672235b527 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Proxy.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/Proxy.java
@@ -69,7 +69,7 @@ public enum Type {
* {@code Socket s = new Socket(Proxy.NO_PROXY);}
*
*/
- public final static Proxy NO_PROXY = new Proxy();
+ public static final Proxy NO_PROXY = new Proxy();
// Creates the proxy that represents a {@code DIRECT} connection.
private Proxy() {
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ResponseCache.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ResponseCache.java
index 7da0ae2775..dc203a32a6 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ResponseCache.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ResponseCache.java
@@ -82,7 +82,7 @@ public abstract class ResponseCache {
* @return the system-wide {@code ResponseCache}
* @since 1.5
*/
- public synchronized static ResponseCache getDefault() {
+ public static synchronized ResponseCache getDefault() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
/* J2ObjC removed.
@@ -107,7 +107,7 @@ public synchronized static ResponseCache getDefault() {
* @see #getDefault()
* @since 1.5
*/
- public synchronized static void setDefault(ResponseCache responseCache) {
+ public static synchronized void setDefault(ResponseCache responseCache) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
/* J2ObjC removed.
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ServerSocket.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ServerSocket.java
index 334314d708..a8ad7692da 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ServerSocket.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/ServerSocket.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,14 +24,20 @@
*/
package java.net;
-
+/* J2ObjC removed
+import sun.security.util.SecurityConstants;
+*/
import java.io.FileDescriptor;
import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.nio.channels.ServerSocketChannel;
/* J2ObjC removed
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
- */
+*/
+import java.util.Set;
+import java.util.Collections;
/**
* This class implements server sockets. A server socket waits for
@@ -48,7 +54,7 @@
* @see java.net.SocketImpl
* @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
* @see java.nio.channels.ServerSocketChannel
- * @since JDK1.0
+ * @since 1.0
*/
public
class ServerSocket implements java.io.Closeable {
@@ -73,12 +79,29 @@ class ServerSocket implements java.io.Closeable {
/**
* Package-private constructor to create a ServerSocket associated with
* the given SocketImpl.
+ *
+ * @throws SecurityException if a security manager is set and
+ * its {@code checkPermission} method doesn't allow
+ * {@code NetPermission("setSocketImpl")}.
*/
ServerSocket(SocketImpl impl) {
+ checkPermission();
this.impl = impl;
impl.setServerSocket(this);
}
+ private static Void checkPermission() {
+ // BEGIN Android-removed: SM is no-op.
+ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ */
+ // END Android-removed: SM is no-op.
+ return null;
+ }
+
/**
* Creates an unbound server socket.
*
@@ -159,7 +182,6 @@ public ServerSocket(int port) throws IOException {
* or may choose to ignore the parameter altogther. The value provided
* should be greater than {@code 0}. If it is less than or equal to
* {@code 0}, then an implementation specific default will be used.
- *
*
* @param port the port number, or {@code 0} to use a port
* number that is automatically allocated.
@@ -208,7 +230,7 @@ public ServerSocket(int port, int backlog) throws IOException {
* or may choose to ignore the parameter altogther. The value provided
* should be greater than {@code 0}. If it is less than or equal to
* {@code 0}, then an implementation specific default will be used.
- *
+ *
* @param port the port number, or {@code 0} to use a port
* number that is automatically allocated.
* @param backlog requested maximum length of the queue of incoming
@@ -226,7 +248,7 @@ public ServerSocket(int port, int backlog) throws IOException {
* @see SocketOptions
* @see SocketImpl
* @see SecurityManager#checkListen
- * @since JDK1.1
+ * @since 1.1
*/
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
setImpl();
@@ -324,7 +346,7 @@ void createImpl() throws SocketException {
*
* If the address is {@code null}, then the system will pick up
* an ephemeral port and a valid local address to bind the socket.
- *
+ *
* @param endpoint The IP address and port number to bind to.
* @throws IOException if the bind operation fails, or if the socket
* is already bound.
@@ -535,7 +557,7 @@ public Socket accept() throws IOException {
* and the channel is in non-blocking mode
* @throws IOException if an I/O error occurs when waiting
* for a connection.
- * @since JDK1.1
+ * @since 1.1
* @revised 1.4
* @spec JSR-51
*/
@@ -552,6 +574,8 @@ protected final void implAccept(Socket s) throws IOException {
si.address = new InetAddress();
si.fd = new FileDescriptor();
getImpl().accept(si);
+ // Android-removed: SocketCleanable is unsupported
+ // SocketCleanable.register(si.fd); // raw fd has been set
SecurityManager security = System.getSecurityManager();
if (security != null) {
@@ -652,13 +676,13 @@ public boolean isClosed() {
* @param timeout the specified timeout, in milliseconds
* @exception SocketException if there is an error in
* the underlying protocol, such as a TCP error.
- * @since JDK1.1
+ * @since 1.1
* @see #getSoTimeout()
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
if (isClosed())
throw new SocketException("Socket is closed");
- getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+ getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
}
/**
@@ -666,7 +690,7 @@ public synchronized void setSoTimeout(int timeout) throws SocketException {
* 0 returns implies that the option is disabled (i.e., timeout of infinity).
* @return the {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} value
* @exception IOException if an I/O error occurs
- * @since JDK1.1
+ * @since 1.1
* @see #setSoTimeout(int)
*/
public synchronized int getSoTimeout() throws IOException {
@@ -855,7 +879,7 @@ public synchronized void setReceiveBufferSize (int size) throws SocketException
}
if (isClosed())
throw new SocketException("Socket is closed");
- getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+ getImpl().setOption(SocketOptions.SO_RCVBUF, size);
}
/**
@@ -929,6 +953,123 @@ public void setPerformancePreferences(int connectionTime,
/* Not implemented yet */
}
+ /**
+ * Sets the value of a socket option.
+ *
+ * @param
+ *
* @param impl an instance of a SocketImpl
* the subclass wishes to use on the Socket.
*
* @exception SocketException if there is an error in the underlying protocol,
* such as a TCP error.
- * @since JDK1.1
+ *
+ * @throws SecurityException if {@code impl} is non-null and a security manager is set
+ * and its {@code checkPermission} method doesn't allow {@code NetPermission("setSocketImpl")}.
+ *
+ * @since 1.1
*/
protected Socket(SocketImpl impl) throws SocketException {
+ checkPermission(impl);
this.impl = impl;
if (impl != null) {
checkOldImpl();
@@ -177,6 +187,21 @@ protected Socket(SocketImpl impl) throws SocketException {
}
}
+ private static Void checkPermission(SocketImpl impl) {
+ // BEGIN Android-removed: SM is no-op.
+ /*
+ if (impl == null) {
+ return null;
+ }
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ */
+ // END Android-removed: SM is no-op.
+ return null;
+ }
+
/**
* Creates a stream socket and connects it to the specified port
* number on the named host.
@@ -286,7 +311,7 @@ public Socket(InetAddress address, int port) throws IOException {
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
* @see SecurityManager#checkConnect
- * @since JDK1.1
+ * @since 1.1
*/
public Socket(String host, int port, InetAddress localAddr,
int localPort) throws IOException {
@@ -328,7 +353,7 @@ public Socket(String host, int port, InetAddress localAddr,
* which is between 0 and 65535, inclusive.
* @exception NullPointerException if {@code address} is null.
* @see SecurityManager#checkConnect
- * @since JDK1.1
+ * @since 1.1
*/
public Socket(InetAddress address, int port, InetAddress localAddr,
int localPort) throws IOException {
@@ -525,7 +550,7 @@ private void checkOldImpl() {
/* J2ObjC modified.
oldImpl = AccessController.doPrivileged
- (new PrivilegedAction
+ *
* @author David Brown
+ * @since 1.1
*/
@@ -61,21 +62,21 @@ public interface SocketOptions {
* If the requested option is binary, it can be set using this method by
* a java.lang.Boolean:
*
* For options that take a particular type as a parameter,
* getOption(int) will return the parameter's value, else
- * it will return java.lang.Boolean(false):
+ * it will return java.lang.Boolean.FALSE:
*
+ * Valid for: SocketImpl, DatagramSocketImpl
+ *
+ * @since 9
+ * @see StandardSocketOptions#SO_REUSEPORT
+ */
+ @Native public static final int SO_REUSEPORT = 0x0E;
/**
* Sets SO_BROADCAST for a socket. This option enables and disables
@@ -179,7 +191,7 @@ public interface SocketOptions {
* @since 1.4
*/
- @Native public final static int SO_BROADCAST = 0x0020;
+ @Native public static final int SO_BROADCAST = 0x0020;
/** Set which outgoing interface on which to send multicast packets.
* Useful on hosts with multiple network interfaces, where applications
@@ -191,7 +203,7 @@ public interface SocketOptions {
* @see MulticastSocket#getInterface()
*/
- @Native public final static int IP_MULTICAST_IF = 0x10;
+ @Native public static final int IP_MULTICAST_IF = 0x10;
/** Same as above. This option is introduced so that the behaviour
* with IP_MULTICAST_IF will be kept the same as before, while
@@ -203,7 +215,7 @@ public interface SocketOptions {
* @see MulticastSocket#getNetworkInterface()
* @since 1.4
*/
- @Native public final static int IP_MULTICAST_IF2 = 0x1f;
+ @Native public static final int IP_MULTICAST_IF2 = 0x1f;
/**
* This option enables or disables local loopback of multicast datagrams.
@@ -211,7 +223,7 @@ public interface SocketOptions {
* @since 1.4
*/
- @Native public final static int IP_MULTICAST_LOOP = 0x12;
+ @Native public static final int IP_MULTICAST_LOOP = 0x12;
/**
* This option sets the type-of-service or traffic class field
@@ -219,7 +231,7 @@ public interface SocketOptions {
* @since 1.4
*/
- @Native public final static int IP_TOS = 0x3;
+ @Native public static final int IP_TOS = 0x3;
/**
* Specify a linger-on-close timeout. This option disables/enables
@@ -237,7 +249,7 @@ public interface SocketOptions {
* @see Socket#setSoLinger
* @see Socket#getSoLinger
*/
- @Native public final static int SO_LINGER = 0x0080;
+ @Native public static final int SO_LINGER = 0x0080;
/** Set a timeout on blocking Socket operations:
* The value of this socket option is a {@code Boolean} that represents
+ * whether the option is enabled or disabled. The exact semantics of this
+ * socket option are socket type and system dependent.
+ *
+ * In the case of stream-oriented sockets, this socket option usually allows
+ * multiple listening sockets to be bound to both same address
+ * and same port.
+ *
+ * For datagram-oriented sockets the socket option usually allows
+ * multiple UDP sockets to be bound to the same address and port.
+ *
+ * An implementation allows this socket option to be set before the
+ * socket is bound or connected. Changing the value of this socket option
+ * after the socket is bound has no effect.
+ *
+ * @since 9
+ */
+ public static final SocketOption A character is encoded by replacing it
* with the sequence of escaped octets that represent that character in the
- * UTF-8 character set. The Euro currency symbol ({@code '\u20AC'}),
+ * UTF-8 character set. The Euro currency symbol ({@code '\u005Cu20AC'}),
* for example, is encoded as {@code "%E2%82%AC"}. (Deviation from
* RFC 2396, which does not specify any particular character
* set.) This convenience method works as if invoking it were equivalent to
- * evaluating the expression {@code new URL(this.toString())} after
+ * evaluating the expression {@code new URL(this.toString())} after
* first checking that this URI is absolute. The ordering of URIs is defined as follows: Two URIs with different schemes are ordered according the
* ordering of their schemes, without regard to case. Two hierarchical URIs with identical schemes are ordered
* according to the ordering of their authority components: If both authority components are server-based then the URIs
* are ordered according to their user-information components; if these
@@ -2020,6 +2021,8 @@ private static String resolvePath(String base, String child,
}
// 5.2 (6c-f)
+ // Android-changed: App compat. Remove leading dots when resolving path. http://b/25897693
+ // String np = normalize(path);
String np = normalize(path, true);
// 5.2 (6g): If the result is absolute but the path begins with "../",
@@ -2071,8 +2074,10 @@ private static URI resolve(URI base, URI child) {
ru.userInfo = base.userInfo;
ru.port = base.port;
+ // BEGIN Android-changed: App Compat. Handle null and empty path using RFC 3986 logic
+ // http://b/25897693
if (child.path == null || child.path.isEmpty()) {
- // This is an addtional path from RFC 3986 RI, which fixes following RFC 2396
+ // This is an additional path from RFC 3986 RI, which fixes following RFC 2396
// "normal" examples:
// Base: http://a/b/c/d;p?q
// "?y" = "http://a/b/c/d;p?y"
@@ -2080,12 +2085,15 @@ private static URI resolve(URI base, URI child) {
// http://b/25897693
ru.path = base.path;
ru.query = child.query != null ? child.query : base.query;
+ // END Android-changed: App Compat. Handle null and empty path using RFC 3986 logic
} else if ((child.path.length() > 0) && (child.path.charAt(0) == '/')) {
// 5.2 (5): Child path is absolute
//
+ // Android-changed: App Compat. Remove leading dots in path.
// There is an additional step from RFC 3986 RI, requiring to remove dots for
// absolute path as well.
// http://b/25897693
+ // ru.path = child.path;
ru.path = normalize(child.path, true);
} else {
// 5.2 (6): Resolve relative path
@@ -2144,12 +2152,13 @@ private static URI relativize(URI base, URI child) {
String bp = normalize(base.path);
String cp = normalize(child.path);
if (!bp.equals(cp)) {
- // Android-changed: The original OpenJdk implementation would append a trailing slash
- // to paths like "/a/b" before relativizing them. This would relativize /a/b/c to
- // "/c" against "/a/b" the android implementation did not do this. It would assume that
- // "b" wasn't a directory and relativize the path to "/b/c". The spec is pretty vague
- // about this but this change is being made because we have several tests that expect
- // this behaviour.
+ // Android-changed: App Compat. Interpret ambiguous base path as a file, not a directory
+ // Upstream would append '/' to bp if not present, interpreting it as a directory; thus,
+ // /a/b/c relative to /a/b would become /c, whereas Android would relativize to /b/c.
+ // The spec is pretty vague about this but the Android behavior is kept because several
+ // tests enforce it.
+ // if (!bp.endsWith("/"))
+ // bp = bp + "/";
if (bp.indexOf('/') != -1) {
bp = bp.substring(0, bp.lastIndexOf('/') + 1);
}
@@ -2339,6 +2348,8 @@ static private int join(char[] path, int[] segs) {
// Remove "." segments from the given path, and remove segment pairs
// consisting of a non-".." segment followed by a ".." segment.
//
+ // Android-changed: App compat. Remove leading dots when resolving path. http://b/25897693
+ // private static void removeDots(char[] path, int[] segs) {
private static void removeDots(char[] path, int[] segs, boolean removeLeading) {
int ns = segs.length;
int end = path.length - 1;
@@ -2386,10 +2397,11 @@ private static void removeDots(char[] path, int[] segs, boolean removeLeading) {
segs[i] = -1;
segs[j] = -1;
}
+ // Android-added: App compat. Remove leading dots when resolving path.
+ // This is a leading ".." segment. Per RFC 3986 RI, this should be removed as
+ // well. This fixes RFC 2396 "abnormal" examples.
+ // http://b/25897693
} else if (removeLeading) {
- // This is a leading ".." segment. Per RFC 3986 RI, this should be removed as
- // well. This fixes RFC 2396 "abnormal" examples.
- // http://b/25897693
segs[i] = -1;
}
}
@@ -2439,11 +2451,13 @@ private static void maybeAddLeadingDot(char[] path, int[] segs) {
// always retain trailing slashes.
//
private static String normalize(String ps) {
+ // BEGIN Android-changed: App compat. Remove leading dots when resolving path.
+ // Controlled by the "boolean removeLeading" argument added to normalize().
return normalize(ps, false);
}
private static String normalize(String ps, boolean removeLeading) {
-
+ // END Android-changed: App compat. Remove leading dots when resolving path.
// Does this path need normalization?
int ns = needsNormalization(ps); // Number of segments
if (ns < 0)
@@ -2457,6 +2471,8 @@ private static String normalize(String ps, boolean removeLeading) {
split(path, segs);
// Remove dots
+ // Android-changed: App compat. Remove leading dots when resolving path.
+ // removeDots(path, segs);
removeDots(path, segs, removeLeading);
// Prevent scheme-name confusion
@@ -2616,9 +2632,11 @@ private static boolean match(char c, long lowMask, long highMask) {
private static final long L_DASH = lowMask("-");
private static final long H_DASH = highMask("-");
+ // BEGIN Android-added: Allow underscore in hostname.
// UNDERSCORE, for use in domainlabel and toplabel
private static final long L_UNDERSCORE = lowMask("_");
private static final long H_UNDERSCORE = highMask("_");
+ // END Android-added: Allow underscore in hostname.
// Dot, for use in hostnames
private static final long L_DOT = lowMask(".");
@@ -2701,6 +2719,7 @@ private static void appendEncoded(StringBuffer sb, char c) {
// by the given mask pair
//
private static String quote(String s, long lowMask, long highMask) {
+ int n = s.length();
StringBuffer sb = null;
boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
for (int i = 0; i < s.length(); i++) {
@@ -2826,6 +2845,7 @@ private static String decode(String s) {
continue;
}
bb.clear();
+ int ui = i;
for (;;) {
assert (n - i >= 2);
bb.put(decode(s.charAt(++i), s.charAt(++i)));
@@ -3379,6 +3399,8 @@ private int parseIPv4Address(int start, int n) {
return p;
}
+ // Android-changed: Allow underscore in hostname.
+ // Added "_" to the grammars for domainLabel and topLabel.
// hostname = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
// domainlabel = alphanum | alphanum *( alphanum | "-" | "_" ) alphanum
// toplabel = alpha | alpha *( alphanum | "-" | "_" ) alphanum
@@ -3391,20 +3413,23 @@ private int parseHostname(int start, int n)
int l = -1; // Start of last parsed label
do {
- // domainlabel = alphanum [ *( alphanum | "-" | "_" ) alphanum ]
- //
- // The RFCs don't permit underscores in hostnames, but URI has to because a certain
- // large website doesn't seem to care about standards and specs.
+ // Android-changed: Allow underscore in hostname.
+ // RFC 2396 only allows alphanumeric characters and hyphens, but real,
+ // large Internet hosts in the wild use underscore, so we have to allow it.
// http://code.google.com/p/android/issues/detail?id=37577
// http://b/17579865
// http://b/18016625
// http://b/18023709
+
+ // domainlabel = alphanum [ *( alphanum | "-" | "_" ) alphanum ]
q = scan(p, n, L_ALPHANUM, H_ALPHANUM);
if (q <= p)
break;
l = p;
if (q > p) {
p = q;
+ // Android-changed: Allow underscore in hostname.
+ // q = scan(p, n, L_ALPHANUM | L_DASH, H_ALPHANUM | H_DASH);
q = scan(p, n, L_ALPHANUM | L_DASH | L_UNDERSCORE, H_ALPHANUM | H_DASH | H_UNDERSCORE);
if (q > p) {
if (charAt(q - 1) == '-')
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URISyntaxException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URISyntaxException.java
index 8072c37244..17d12bd963 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URISyntaxException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URISyntaxException.java
@@ -121,7 +121,7 @@ public int getIndex() {
* @return A string describing the parse error
*/
public String getMessage() {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append(getReason());
if (index > -1) {
sb.append(" at index ");
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URL.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URL.java
index cb44d1c55d..a3a5e37031 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URL.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URL.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,25 +30,41 @@
import com.google.j2objc.annotations.ObjectiveCName;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.StringTokenizer;
+/* J2ObjC: removed
+import sun.security.util.SecurityConstants;
+*/
/**
- * Class
- * In general, a URL can be broken into several parts. The previous
- * example of a URL indicates that the protocol to use is
- *
+ * The URL above indicates that the protocol to use is
+ * {@code http} (HyperText Transfer Protocol) and that the
* information resides on a host machine named
- *
- * The syntax of
* An application can also specify a "relative URL",
@@ -136,6 +152,10 @@ public final class URL implements java.io.Serializable {
* core classes like ClassLoader reference URL publicly.
*/
+ // Android-changed: Custom built-in URLStreamHandlers for http, https.
+ // static final String BUILTIN_HANDLERS_PREFIX = "sun.net.www.protocol";
+ // J2ObjC removed
+ // private static final Set
+ * Creates a {@code URL} object from the specified
+ * {@code protocol}, {@code host}, {@code port}
+ * number, and {@code file}.
*
- *
*
- * Specifying a
*
* If this is the first URL object being created with the specified
* protocol, a stream protocol handler object, an instance of
- * class Protocol handlers for the following protocols are guaranteed
* to exist on the search path :-
*
* This method is equivalent to calling the four-argument
- * constructor with the arguments being If the handler is not null and there is a security manager,
- * the security manager's
* This constructor is equivalent to a call to the two-argument
- * constructor with a
* For a more detailed description of URL parsing, refer to RFC2396.
*
* @param context the context in which to parse the specification.
- * @param spec the
*
* If the given object is not a URL then this method immediately returns
- *
+ * {@code false}.
*
* Two URL objects are equal if they have the same protocol, reference
* equivalent hosts, have the same port number on the host, and the same
@@ -728,14 +903,14 @@ public String getRef() {
* case).
*
* @param obj the URL to compare against.
- * @return
*
- * @return a hash code for this
*
- * Returns Note, any URL instance that complies with RFC 2396 can be converted
* to a URI. However, some URLs that are not strictly in compliance
* can not be converted to a URI.
@@ -861,6 +1038,7 @@ public URI toURI() throws URISyntaxException {
* int, java.lang.String)
*/
public URLConnection openConnection() throws java.io.IOException {
+ // J2ObjC: modified
return getDelegate().openConnection(this);
}
@@ -876,7 +1054,7 @@ public URLConnection openConnection() throws java.io.IOException {
* @param proxy the Proxy through which this connection
* will be made. If direct connection is desired,
* Proxy.NO_PROXY should be specified.
- * @return a The {@code URLStreamHandlerFactory} instance is used to
+ *construct a stream protocol handler from a protocol name.
+ *
+ * If there is a security manager, this method first calls
+ * the security manager's {@code checkSetFactory} method
+ * to ensure the operation is allowed.
+ * This could result in a SecurityException.
+ *
+ * @param fac the desired factory.
+ * @exception Error if the application has already set a factory.
+ * @exception SecurityException if a security manager exists and its
+ * {@code checkSetFactory} method doesn't allow
+ * the operation.
+ * @see java.net.URL#URL(java.lang.String, java.lang.String,
+ * int, java.lang.String)
+ * @see java.net.URLStreamHandlerFactory
+ * @see SecurityManager#checkSetFactory
+ */
public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) {
+ // J2ObjC: modified
getDelegate().setURLStreamHandlerFactory(fac);
}
+ // END Android-added: Custom built-in URLStreamHandlers for http, https.
+
+ /**
+ * J2ObjC: removed
+ * @serialField protocol String
+ *
+ * @serialField host String
+ *
+ * @serialField port int
+ *
+ * @serialField authority String
+ *
+ * @serialField file String
+ *
+ * @serialField ref String
+ *
+ * @serialField hashCode int
+ *
+
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("protocol", String.class),
+ new ObjectStreamField("host", String.class),
+ new ObjectStreamField("port", int.class),
+ new ObjectStreamField("authority", String.class),
+ new ObjectStreamField("file", String.class),
+ new ObjectStreamField("ref", String.class),
+ // Android-changed: App compat: hashCode should not be serialized.
+ // new ObjectStreamField("hashCode", int.class), };
+ };
+ */
/**
* WriteObject is called to save the state of the URL to an
@@ -974,16 +1213,70 @@ private synchronized void writeObject(java.io.ObjectOutputStream s)
* stream handler.
*/
private synchronized void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException
- {
- s.defaultReadObject(); // read the fields
- if ((handler = getDelegate().getURLStreamHandler(protocol)) == null) {
+ throws IOException, ClassNotFoundException {
+ GetField gf = s.readFields();
+ String protocol = (String)gf.get("protocol", null);
+ if (getDelegate().getURLStreamHandler(protocol) == null) {
throw new IOException("unknown protocol: " + protocol);
}
+ String host = (String)gf.get("host", null);
+ int port = gf.get("port", -1);
+ String authority = (String)gf.get("authority", null);
+ String file = (String)gf.get("file", null);
+ String ref = (String)gf.get("ref", null);
+ // Android-changed: App compat: hashCode should not be serialized.
+ // int hashCode = gf.get("hashCode", -1);
+ final int hashCode = -1;
+ if (authority == null
+ && ((host != null && host.length() > 0) || port != -1)) {
+ if (host == null)
+ host = "";
+ authority = (port == -1) ? host : host + ":" + port;
+ }
+ tempState = new UrlDeserializedState(protocol, host, port, authority,
+ file, ref, hashCode);
+ }
+
+ /*
+ * J2ObjC: removed
+ * Replaces the de-serialized object with an URL object.
+ *
+ * @return a newly created object from the deserialzed state.
+ *
+ * @throws ObjectStreamException if a new object replacing this
+ * object could not be created
+
+
+ private Object readResolve() throws ObjectStreamException {
+
+ URLStreamHandler handler = null;
+ // already been checked in readObject
+ handler = getURLStreamHandler(tempState.getProtocol());
+
+ URL replacementURL = null;
+ if (isBuiltinStreamHandler(handler.getClass().getName())) {
+ replacementURL = fabricateNewURL();
+ } else {
+ replacementURL = setDeserializedFields(handler);
+ }
+ return replacementURL;
+ }
+
+ private URL setDeserializedFields(URLStreamHandler handler) {
+ URL replacementURL;
+ String userInfo = null;
+ String protocol = tempState.getProtocol();
+ String host = tempState.getHost();
+ int port = tempState.getPort();
+ String authority = tempState.getAuthority();
+ String file = tempState.getFile();
+ String ref = tempState.getRef();
+ int hashCode = tempState.getHashCode();
+
// Construct authority part
- if (authority == null &&
- ((host != null && host.length() > 0) || port != -1)) {
+ if (authority == null
+ && ((host != null && host.length() > 0) || port != -1)) {
if (host == null)
host = "";
authority = (port == -1) ? host : host + ":" + port;
@@ -1002,8 +1295,8 @@ private synchronized void readObject(java.io.ObjectInputStream s)
}
// Construct path and query part
- path = null;
- query = null;
+ String path = null;
+ String query = null;
if (file != null) {
// Fix: only do this if hierarchical?
int q = file.lastIndexOf('?');
@@ -1013,8 +1306,68 @@ private synchronized void readObject(java.io.ObjectInputStream s)
} else
path = file;
}
- hashCode = -1;
+
+ // Set the object fields.
+ this.protocol = protocol;
+ this.host = host;
+ this.port = port;
+ this.file = file;
+ this.authority = authority;
+ this.ref = ref;
+ this.hashCode = hashCode;
+ this.handler = handler;
+ this.query = query;
+ this.path = path;
+ this.userInfo = userInfo;
+ replacementURL = this;
+ return replacementURL;
+ }
+
+ private URL fabricateNewURL()
+ throws InvalidObjectException {
+ // create URL string from deserialized object
+ URL replacementURL = null;
+ String urlString = tempState.reconstituteUrlString();
+
+ try {
+ replacementURL = new URL(urlString);
+ } catch (MalformedURLException mEx) {
+ resetState();
+ InvalidObjectException invoEx = new InvalidObjectException(
+ "Malformed URL: " + urlString);
+ invoEx.initCause(mEx);
+ throw invoEx;
+ }
+ replacementURL.setSerializedHashCode(tempState.getHashCode());
+ resetState();
+ return replacementURL;
+ }
+
+ private boolean isBuiltinStreamHandler(String handlerClassName) {
+ // Android-changed: Some built-in handlers (eg. HttpHandler) are not in sun.net.www.protocol.
+ // return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
+ return BUILTIN_HANDLER_CLASS_NAMES.contains(handlerClassName);
+ }
+
+ private void resetState() {
+ this.protocol = null;
+ this.host = null;
+ this.port = -1;
+ this.file = null;
+ this.authority = null;
+ this.ref = null;
+ this.hashCode = -1;
+ this.handler = null;
+ this.query = null;
+ this.path = null;
+ this.userInfo = null;
+ this.tempState = null;
+ }
+
+ private void setSerializedHashCode(int hc) {
+ this.hashCode = hc;
}
+ */
// ----- BEGIN j2objc -----
private static final URLDelegate IMPL = findImplementation();
@@ -1082,6 +1435,8 @@ void setQueryByDelegate(String query) {
class Parts {
String path, query, ref;
+ // Android-changed: App compat. Prepend '/' if host is null / empty.
+ // Parts(String file)
Parts(String file, String host) {
int ind = file.indexOf('#');
ref = ind < 0 ? null: file.substring(ind + 1);
@@ -1093,10 +1448,12 @@ class Parts {
} else {
path = file;
}
+ // BEGIN Android-changed: App compat. Prepend '/' if host is null / empty.
if (path != null && path.length() > 0 && path.charAt(0) != '/' &&
host != null && !host.isEmpty()) {
path = '/' + path;
}
+ // END Android-changed: App compat. Prepend '/' if host is null / empty.
}
String getPath() {
@@ -1111,3 +1468,82 @@ String getRef() {
return ref;
}
}
+
+final class UrlDeserializedState {
+ private final String protocol;
+ private final String host;
+ private final int port;
+ private final String authority;
+ private final String file;
+ private final String ref;
+ private final int hashCode;
+
+ public UrlDeserializedState(String protocol,
+ String host, int port,
+ String authority, String file,
+ String ref, int hashCode) {
+ this.protocol = protocol;
+ this.host = host;
+ this.port = port;
+ this.authority = authority;
+ this.file = file;
+ this.ref = ref;
+ this.hashCode = hashCode;
+ }
+
+ String getProtocol() {
+ return protocol;
+ }
+
+ String getHost() {
+ return host;
+ }
+
+ String getAuthority () {
+ return authority;
+ }
+
+ int getPort() {
+ return port;
+ }
+
+ String getFile () {
+ return file;
+ }
+
+ String getRef () {
+ return ref;
+ }
+
+ int getHashCode () {
+ return hashCode;
+ }
+
+ String reconstituteUrlString() {
+
+ // pre-compute length of StringBuilder
+ int len = protocol.length() + 1;
+ if (authority != null && authority.length() > 0)
+ len += 2 + authority.length();
+ if (file != null) {
+ len += file.length();
+ }
+ if (ref != null)
+ len += 1 + ref.length();
+ StringBuilder result = new StringBuilder(len);
+ result.append(protocol);
+ result.append(":");
+ if (authority != null && authority.length() > 0) {
+ result.append("//");
+ result.append(authority);
+ }
+ if (file != null) {
+ result.append(file);
+ }
+ if (ref != null) {
+ result.append("#");
+ result.append(ref);
+ }
+ return result.toString();
+ }
+}
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLDecoder.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLDecoder.java
index 8b14eb86da..0d2d43102c 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLDecoder.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLDecoder.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,10 @@
package java.net;
import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Objects;
/**
* Utility class for HTML form decoding. This class contains static methods
@@ -107,41 +111,73 @@ public static String decode(String s) {
}
/**
- * Decodes a {@code application/x-www-form-urlencoded} string using a specific
- * encoding scheme.
- * The supplied encoding is used to determine
- * what characters are represented by any consecutive sequences of the
- * form "{@code %xy}".
+ * Decodes an {@code application/x-www-form-urlencoded} string using
+ * a specific encoding scheme.
+ *
*
- * Note: The
- * World Wide Web Consortium Recommendation states that
- * UTF-8 should be used. Not doing so may introduce
- * incompatibilities.
+ * This method behaves the same as {@linkplain String decode(String s, Charset charset)}
+ * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset}
+ * using the given encoding name.
+ *
+ * @implNote This implementation will throw an {@link java.lang.IllegalArgumentException}
+ * when illegal strings are encountered.
*
* @param s the {@code String} to decode
* @param enc The name of a supported
* character
* encoding.
* @return the newly decoded {@code String}
- * @exception UnsupportedEncodingException
+ * @throws UnsupportedEncodingException
* If character encoding needs to be consulted, but
* named character encoding is not supported
* @see URLEncoder#encode(java.lang.String, java.lang.String)
* @since 1.4
*/
- public static String decode(String s, String enc)
- throws UnsupportedEncodingException{
+ public static String decode(String s, String enc) throws UnsupportedEncodingException {
+ if (enc.isEmpty()) {
+ throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
+ }
+
+ try {
+ Charset charset = Charset.forName(enc);
+ return decode(s, charset);
+ } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+ throw new UnsupportedEncodingException(enc);
+ }
+ }
+ /**
+ * Decodes an {@code application/x-www-form-urlencoded} string using
+ * a specific {@linkplain java.nio.charset.Charset Charset}.
+ * The supplied charset is used to determine
+ * what characters are represented by any consecutive sequences of the
+ * form "{@code %xy}".
+ *
+ * Note: The
+ * World Wide Web Consortium Recommendation states that
+ * UTF-8 should be used. Not doing so may introduce
+ * incompatibilities.
+ *
+ * @implNote This implementation will throw an {@link java.lang.IllegalArgumentException}
+ * when illegal strings are encountered.
+ *
+ * @param s the {@code String} to decode
+ * @param charset the given charset
+ * @return the newly decoded {@code String}
+ * @throws NullPointerException if {@code s} or {@code charset} is {@code null}
+ * @throws IllegalArgumentException if the implementation encounters illegal
+ * characters
+ * @see URLEncoder#encode(java.lang.String, java.nio.charset.Charset)
+ * @since 10
+ */
+ public static String decode(String s, Charset charset) {
+ Objects.requireNonNull(charset, "Charset");
boolean needToChange = false;
int numChars = s.length();
- StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
+ StringBuilder sb = new StringBuilder(numChars > 500 ? numChars / 2 : numChars);
int i = 0;
- if (enc.length() == 0) {
- throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
- }
-
char c;
byte[] bytes = null;
while (i < numChars) {
@@ -196,7 +232,7 @@ public static String decode(String s, String enc)
throw new IllegalArgumentException(
"URLDecoder: Incomplete trailing escape (%) pattern");
- sb.append(new String(bytes, 0, pos, enc));
+ sb.append(new String(bytes, 0, pos, charset));
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
"URLDecoder: Illegal hex characters in escape (%) pattern - "
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLEncoder.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLEncoder.java
index 8d26d2e0e8..43a3544dc3 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLEncoder.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,22 +25,16 @@
package java.net;
-import java.io.ByteArrayOutputStream;
-import java.io.BufferedWriter;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.CharArrayWriter;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException ;
import java.util.BitSet;
+import java.util.Objects;
/* J2ObjC removed.
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
- */
+*/
/**
* Utility class for HTML form encoding. This class contains static methods
@@ -79,7 +73,7 @@
* character @ is encoded as one byte 40 (hex).
*
* @author Herb Jellinek
- * @since JDK1.0
+ * @since 1.0
*/
public class URLEncoder {
static BitSet dontNeedEncoding;
@@ -182,44 +176,60 @@ public static String encode(String s) {
/**
* Translates a string into {@code application/x-www-form-urlencoded}
- * format using a specific encoding scheme. This method uses the
- * supplied encoding scheme to obtain the bytes for unsafe
- * characters.
+ * format using a specific encoding scheme.
*
- * Note: The
- * World Wide Web Consortium Recommendation states that
- * UTF-8 should be used. Not doing so may introduce
- * incompatibilities.
+ * This method behaves the same as {@linkplain String encode(String s, Charset charset)}
+ * except that it will {@linkplain java.nio.charset.Charset#forName look up the charset}
+ * using the given encoding name.
*
* @param s {@code String} to be translated.
* @param enc The name of a supported
* character
* encoding.
* @return the translated {@code String}.
- * @exception UnsupportedEncodingException
+ * @throws UnsupportedEncodingException
* If the named encoding is not supported
* @see URLDecoder#decode(java.lang.String, java.lang.String)
* @since 1.4
*/
public static String encode(String s, String enc)
throws UnsupportedEncodingException {
-
- boolean needToChange = false;
- StringBuffer out = new StringBuffer(s.length());
- Charset charset;
- CharArrayWriter charArrayWriter = new CharArrayWriter();
-
- if (enc == null)
+ if (enc == null) {
throw new NullPointerException("charsetName");
+ }
try {
- charset = Charset.forName(enc);
- } catch (IllegalCharsetNameException e) {
- throw new UnsupportedEncodingException(enc);
- } catch (UnsupportedCharsetException e) {
+ Charset charset = Charset.forName(enc);
+ return encode(s, charset);
+ } catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
throw new UnsupportedEncodingException(enc);
}
+ }
+
+ /**
+ * Translates a string into {@code application/x-www-form-urlencoded}
+ * format using a specific {@linkplain java.nio.charset.Charset Charset}.
+ * This method uses the supplied charset to obtain the bytes for unsafe
+ * characters.
+ *
+ * Note: The
+ * World Wide Web Consortium Recommendation states that
+ * UTF-8 should be used. Not doing so may introduce incompatibilities.
+ *
+ * @param s {@code String} to be translated.
+ * @param charset the given charset
+ * @return the translated {@code String}.
+ * @throws NullPointerException if {@code s} or {@code charset} is {@code null}.
+ * @see URLDecoder#decode(java.lang.String, java.nio.charset.Charset)
+ * @since 10
+ */
+ public static String encode(String s, Charset charset) {
+ Objects.requireNonNull(charset, "charset");
+
+ boolean needToChange = false;
+ StringBuilder out = new StringBuilder(s.length());
+ CharArrayWriter charArrayWriter = new CharArrayWriter();
for (int i = 0; i < s.length();) {
int c = (int) s.charAt(i);
@@ -239,7 +249,7 @@ public static String encode(String s, String enc)
/*
* If this character represents the start of a Unicode
* surrogate pair, then pass in two characters. It's not
- * clear what should be done if a bytes reserved in the
+ * clear what should be done if a byte reserved in the
* surrogate pairs range occurs outside of a legal
* surrogate pair. For now, just treat it as if it were
* any other character.
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandler.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandler.java
index a56c0a1c83..5896975ac8 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -134,9 +134,9 @@ protected void parseURL(URL u, String spec, int start, int limit) {
boolean isRelPath = false;
boolean queryOnly = false;
- // BEGIN Android-changed
+ // BEGIN Android-changed: App compat.
boolean querySet = false;
- // END Android-changed
+ // END Android-changed: App compat.
// FIX: should not assume query if opaque
// Strip off the query part
@@ -148,31 +148,44 @@ protected void parseURL(URL u, String spec, int start, int limit) {
if (limit > queryStart)
limit = queryStart;
spec = spec.substring(0, queryStart);
- // BEGIN Android-changed
+ // BEGIN Android-changed: App compat.
querySet = true;
- // END Android-changed
+ // END Android-changed: App compat.
}
}
int i = 0;
// Parse the authority part if any
- // BEGIN Android-changed
+ // BEGIN Android-changed: App compat.
// boolean isUNCName = (start <= limit - 4) &&
// (spec.charAt(start) == '/') &&
// (spec.charAt(start + 1) == '/') &&
// (spec.charAt(start + 2) == '/') &&
// (spec.charAt(start + 3) == '/');
boolean isUNCName = false;
- // END Android-changed
+ // END Android-changed: App compat.
if (!isUNCName && (start <= limit - 2) && (spec.charAt(start) == '/') &&
(spec.charAt(start + 1) == '/')) {
start += 2;
+ // BEGIN Android-changed: Check for all hostname termination chars. http://b/110955991
+ /*
i = spec.indexOf('/', start);
if (i < 0 || i > limit) {
i = spec.indexOf('?', start);
if (i < 0 || i > limit)
i = limit;
}
+ */
+ LOOP: for (i = start; i < limit; i++) {
+ switch (spec.charAt(i)) {
+ case '/': // Start of path
+ case '\\': // Start of path - see https://url.spec.whatwg.org/#host-state
+ case '?': // Start of query
+ case '#': // Start of fragment
+ break LOOP;
+ }
+ }
+ // END Android-changed: Check for all hostname termination chars. http://b/110955991
host = authority = spec.substring(start, i);
@@ -226,7 +239,7 @@ protected void parseURL(URL u, String spec, int start, int limit) {
if (ind >= 0) {
// port can be null according to RFC2396
if (host.length() > (ind + 1)) {
- // BEGIN Android-changed
+ // BEGIN Android-changed: App compat.
// port = Integer.parseInt(host.substring(ind + 1));
char firstPortChar = host.charAt(ind+1);
if (firstPortChar >= '0' && firstPortChar <= '9') {
@@ -235,7 +248,7 @@ protected void parseURL(URL u, String spec, int start, int limit) {
throw new IllegalArgumentException("invalid port: " +
host.substring(ind + 1));
}
- // END Android-changed
+ // END Android-changed: App compat.
}
host = host.substring(0, ind);
}
@@ -248,16 +261,16 @@ protected void parseURL(URL u, String spec, int start, int limit) {
port);
start = i;
- // BEGIN Android-changed
// If the authority is defined then the path is defined by the
// spec only; See RFC 2396 Section 5.2.4.
+ // BEGIN Android-changed: App compat.
// if (authority != null && authority.length() > 0)
// path = "";
path = null;
if (!querySet) {
query = null;
}
- // END Android-changed
+ // END Android-changed: App compat.
}
if (host == null) {
@@ -266,7 +279,9 @@ protected void parseURL(URL u, String spec, int start, int limit) {
// Parse the file path if any
if (start < limit) {
- if (spec.charAt(start) == '/') {
+ // Android-changed: Check for all hostname termination chars. http://b/110955991
+ // if (spec.charAt(start) == '/') {
+ if (spec.charAt(start) == '/' || spec.charAt(start) == '\\') {
path = spec.substring(start, limit);
} else if (path != null && path.length() > 0) {
isRelPath = true;
@@ -282,21 +297,21 @@ protected void parseURL(URL u, String spec, int start, int limit) {
path = seperator + spec.substring(start, limit);
}
}
- // BEGIN Android-changed
+ // BEGIN Android-changed: App compat.
//else if (queryOnly && path != null) {
// int ind = path.lastIndexOf('/');
// if (ind < 0)
// ind = 0;
// path = path.substring(0, ind) + "/";
//}
- // END Android-changed
+ // END Android-changed: App compat.
if (path == null)
path = "";
- // BEGIN Android-changed
+ // BEGIN Android-changed: always assume isRelPath is true.
//if (isRelPath) {
if (true) {
- // END Android-changed
+ // END Android-changed: always assume isRelPath is true.
// Remove embedded /./
while ((i = path.indexOf("/./")) >= 0) {
path = path.substring(0, i) + path.substring(i + 2);
@@ -304,20 +319,22 @@ protected void parseURL(URL u, String spec, int start, int limit) {
// Remove embedded /../ if possible
i = 0;
while ((i = path.indexOf("/../", i)) >= 0) {
- // BEGIN Android-changed
+ // BEGIN Android-changed: App compat.
/*
* Trailing /../
*/
if (i == 0) {
path = path.substring(i + 3);
i = 0;
- // END Android-changed
+ // END Android-changed: App compat.
/*
* A "/../" will cancel the previous segment and itself,
* unless that segment is a "/../" itself
* i.e. "/a/b/../c" becomes "/a/c"
* but "/../../a" should stay unchanged
*/
+ // Android-changed: App compat.
+ // if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
} else if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
(path.indexOf("/../", limit) != 0)) {
path = path.substring(0, limit) + path.substring(i + 3);
@@ -343,7 +360,7 @@ protected void parseURL(URL u, String spec, int start, int limit) {
if (path.endsWith("/."))
path = path.substring(0, path.length() -1);
- // Remove trailing ?
+ // Android-changed: App compat: Remove trailing '?'.
if (path.endsWith("?"))
path = path.substring(0, path.length() -1);
}
@@ -374,6 +391,7 @@ protected int getDefaultPort() {
* @since 1.3
*/
protected boolean equals(URL u1, URL u2) {
+ // Android-changed: Avoid network I/O.
return Objects.equals(u1.getRef(), u2.getRef()) &&
Objects.equals(u1.getQuery(), u2.getQuery()) &&
// sameFile compares the protocol, file, port & host components of
@@ -390,6 +408,7 @@ protected boolean equals(URL u1, URL u2) {
* @since 1.3
*/
protected int hashCode(URL u) {
+ // Android-changed: Avoid network I/O.
// Hash on the same set of fields that we compare in equals().
return Objects.hash(
u.getRef(),
@@ -425,13 +444,14 @@ protected boolean sameFile(URL u1, URL u2) {
// Compare the ports.
int port1, port2;
+ // J2ObjC modified
try {
port1 = (u1.getPort() != -1)
? u1.getPort() : ((URLStreamHandler) u1.getHandler()).getDefaultPort();
port2 = (u2.getPort() != -1)
? u2.getPort() : ((URLStreamHandler) u2.getHandler()).getDefaultPort();
- if (port1 != port2)
- return false;
+ if (port1 != port2)
+ return false;
} catch (MalformedURLException e) {
return false;
}
@@ -509,6 +529,8 @@ protected String toExternalForm(URL u) {
if (u.getRef() != null)
len += 1 + u.getRef().length();
+ // BEGIN Android-changed: New toExternalForm variant that optionally escapes illegal chars.
+ // TODO: The variant has been removed. We can potentially revert the change
StringBuilder result = new StringBuilder(len);
result.append(u.getProtocol());
result.append(":");
@@ -520,6 +542,7 @@ protected String toExternalForm(URL u) {
if (fileAndQuery != null) {
result.append(fileAndQuery);
}
+ // END Android-changed: New toExternalForm variant that optionally escapes illegal chars.
if (u.getRef() != null) {
result.append("#");
result.append(u.getRef());
@@ -527,6 +550,8 @@ protected String toExternalForm(URL u) {
return result.toString();
}
+ // Android-changed: Removed @see tag (target is package-private).
+ // @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
/**
* Sets the fields of the {@code URL} argument to the indicated values.
* Only classes derived from URLStreamHandler are able
@@ -543,7 +568,6 @@ protected String toExternalForm(URL u) {
* @param ref the reference.
* @exception SecurityException if the protocol handler of the URL is
* different from this one
- * @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
* @since 1.3
*/
protected void setURL(URL u, String protocol, String host, int port,
@@ -551,8 +575,8 @@ protected void setURL(URL u, String protocol, String host, int port,
String query, String ref) {
try {
if (this != u.getHandler()) {
- throw new SecurityException("handler for url different from " +
- "this handler");
+ throw new SecurityException("handler for url different from " +
+ "this handler");
}
} catch (MalformedURLException e) {
// Ignore.
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandlerFactory.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandlerFactory.java
index e46e02857e..c35af100b9 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandlerFactory.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/URLStreamHandlerFactory.java
@@ -28,14 +28,14 @@
/**
* This interface defines a factory for {@code URL} stream
* protocol handlers.
- *
- * It is used by the {@code URL} class to create a
- * {@code URLStreamHandler} for a specific protocol.
+ *
+ * A URL stream handler factory is used as specified in the
+ * {@linkplain java.net.URL#URL(String,String,int,String) URL constructor}.
*
* @author Arthur van Hoff
* @see java.net.URL
* @see java.net.URLStreamHandler
- * @since JDK1.0
+ * @since 1.0
*/
public interface URLStreamHandlerFactory {
/**
@@ -44,7 +44,9 @@ public interface URLStreamHandlerFactory {
*
* @param protocol the protocol ("{@code ftp}",
* "{@code http}", "{@code nntp}", etc.).
- * @return a {@code URLStreamHandler} for the specific protocol.
+ * @return a {@code URLStreamHandler} for the specific protocol, or {@code
+ * null} if this factory cannot create a handler for the specific
+ * protocol
* @see java.net.URLStreamHandler
*/
URLStreamHandler createURLStreamHandler(String protocol);
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownHostException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownHostException.java
index 21a9d1450c..9a9fea53fa 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownHostException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownHostException.java
@@ -31,7 +31,7 @@
* Thrown to indicate that the IP address of a host could not be determined.
*
* @author Jonathan Payne
- * @since JDK1.0
+ * @since 1.0
*/
public
class UnknownHostException extends IOException {
@@ -41,10 +41,10 @@ class UnknownHostException extends IOException {
* Constructs a new {@code UnknownHostException} with the
* specified detail message.
*
- * @param host the detail message.
+ * @param message the detail message.
*/
- public UnknownHostException(String host) {
- super(host);
+ public UnknownHostException(String message) {
+ super(message);
}
/**
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownServiceException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownServiceException.java
index 4eea4a769d..7daa8a47c6 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownServiceException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/UnknownServiceException.java
@@ -34,7 +34,7 @@
* read-only URL connection.
*
* @author unascribed
- * @since JDK1.0
+ * @since 1.0
*/
public class UnknownServiceException extends IOException {
private static final long serialVersionUID = -4169033248853639508L;
+ *
+ * These flags can be logically OR'ed together.
*
- *
+ * {@link #toASCII(String, int) toASCII}(input, 0);
+ *
+ *
+ * @param input the string to be processed
*
- * @param input the Unicode name
- * @return the ACE name
- * @throws IllegalArgumentException if {@code input} does not conform to RFC 3490
+ * @return the translated {@code String}
+ *
+ * @throws IllegalArgumentException if the input string doesn't conform to RFC 3490 specification
*/
public static String toASCII(String input) {
return toASCII(input, 0);
}
+
/**
- * Translates a string from ASCII Compatible Encoding (ACE) to Unicode
- * according to the algorithm defined in RFC 3490.
+ * Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
+ * as defined by the ToUnicode operation of RFC 3490.
+ *
+ *
+ * {@link #toUnicode(String, int) toUnicode}(input, 0);
+ *
*
- * @param input the ACE name
- * @return the Unicode name
+ * @param input the string to be processed
+ *
+ * @return the translated {@code String}
*/
public static String toUnicode(String input) {
return NativeIDN.toUnicode(input, 0);
}
+
+
+ /* ---------------- Private members -------------- */
+
+ // Android-removed: Private helper methods, unused because we use ICU.
+ /*
+ // ACE Prefix is "xn--"
+ private static final String ACE_PREFIX = "xn--";
+ private static final int ACE_PREFIX_LENGTH = ACE_PREFIX.length();
+
+ private static final int MAX_LABEL_LENGTH = 63;
+
+ // single instance of nameprep
+ private static StringPrep namePrep = null;
+
+ static {
+ InputStream stream = null;
+
+ try {
+ final String IDN_PROFILE = "uidna.spp";
+ if (System.getSecurityManager() != null) {
+ stream = AccessController.doPrivileged(new PrivilegedAction Textual representation of IP addresses
+ * Textual representation of IP addresses
*
* Textual representation of IPv4 address used as input to methods
* takes one of the following forms:
*
- *
+ *
- *
- * {@code d.d.d.d}
- * {@code d.d.d}
- * {@code d.d}
- * {@code d}
*
*
+ *
*
* @param size the size to which to set the receive buffer
@@ -1340,7 +1363,7 @@ public synchronized void setReceiveBufferSize(int size)
}
if (isClosed())
throw new SocketException("Socket is closed");
- getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+ getImpl().setOption(SocketOptions.SO_RCVBUF, size);
}
/**
@@ -1806,9 +1829,104 @@ public void setPerformancePreferences(int connectionTime,
/* Not implemented yet */
}
+
+ /**
+ * Sets the value of a socket option.
+ *
+ * @param
- * s.setOption(TCP_NODELAY, new Boolean(true));
+ * s.setOption(TCP_NODELAY, Boolean.TRUE);
* // OK - enables TCP_NODELAY, a binary option
*
*
- * Any option can be disabled using this method with a Boolean(false):
+ * Any option can be disabled using this method with a Boolean.FALSE:
*
- * s.setOption(TCP_NODELAY, new Boolean(false));
+ * s.setOption(TCP_NODELAY, Boolean.FALSE);
* // OK - disables TCP_NODELAY
- * s.setOption(SO_LINGER, new Boolean(false));
+ * s.setOption(SO_LINGER, Boolean.FALSE);
* // OK - disables SO_LINGER
*
*
* For an option that has a notion of on and off, and requires
* a non-boolean parameter, setting its value to anything other than
- * Boolean(false) implicitly enables it.
+ * Boolean.FALSE implicitly enables it.
*
* Throws SocketException if the option is unrecognized,
* the socket is closed, or some low-level error occurred
@@ -91,8 +92,8 @@ public interface SocketOptions {
/**
* Fetch the value of an option.
- * Binary options will return java.lang.Boolean(true)
- * if enabled, java.lang.Boolean(false) if disabled, e.g.:
+ * Binary options will return java.lang.Boolean.TRUE
+ * if enabled, java.lang.Boolean.FALSE if disabled, e.g.:
*
* SocketImpl s;
* ...
@@ -105,13 +106,13 @@ public interface SocketOptions {
*
* Object o = s.getOption(SO_LINGER);
* if (o instanceof Integer) {
* System.out.print("Linger time is " + ((Integer)o).intValue());
* } else {
- * // the true type of o is java.lang.Boolean(false);
+ * // the true type of o is java.lang.Boolean.FALSE;
* }
*
*
@@ -139,7 +140,7 @@ public interface SocketOptions {
* @see Socket#getTcpNoDelay
*/
- @Native public final static int TCP_NODELAY = 0x0001;
+ @Native public static final int TCP_NODELAY = 0x0001;
/**
* Fetch the local address binding of a socket (this option cannot
@@ -160,7 +161,7 @@ public interface SocketOptions {
* @see DatagramSocket#getLocalAddress
*/
- @Native public final static int SO_BINDADDR = 0x000F;
+ @Native public static final int SO_BINDADDR = 0x000F;
/** Sets SO_REUSEADDR for a socket. This is used only for MulticastSockets
* in java, and it is set by default for MulticastSockets.
@@ -168,7 +169,18 @@ public interface SocketOptions {
* Valid for: DatagramSocketImpl
*/
- @Native public final static int SO_REUSEADDR = 0x04;
+ @Native public static final int SO_REUSEADDR = 0x04;
+
+ /** Sets SO_REUSEPORT for a socket. This option enables and disables
+ * the ability to have multiple sockets listen to the same address
+ * and port.
+ *
@@ -258,7 +270,7 @@ public interface SocketOptions {
* @see ServerSocket#setSoTimeout
* @see DatagramSocket#setSoTimeout
*/
- @Native public final static int SO_TIMEOUT = 0x1006;
+ @Native public static final int SO_TIMEOUT = 0x1006;
/**
* Set a hint the size of the underlying buffers used by the
@@ -275,7 +287,7 @@ public interface SocketOptions {
* @see DatagramSocket#setSendBufferSize
* @see DatagramSocket#getSendBufferSize
*/
- @Native public final static int SO_SNDBUF = 0x1001;
+ @Native public static final int SO_SNDBUF = 0x1001;
/**
* Set a hint the size of the underlying buffers used by the
@@ -293,7 +305,7 @@ public interface SocketOptions {
* @see DatagramSocket#setReceiveBufferSize
* @see DatagramSocket#getReceiveBufferSize
*/
- @Native public final static int SO_RCVBUF = 0x1002;
+ @Native public static final int SO_RCVBUF = 0x1002;
/**
* When the keepalive option is set for a TCP socket and no data
@@ -316,7 +328,7 @@ public interface SocketOptions {
* @see Socket#setKeepAlive
* @see Socket#getKeepAlive
*/
- @Native public final static int SO_KEEPALIVE = 0x0008;
+ @Native public static final int SO_KEEPALIVE = 0x0008;
/**
* When the OOBINLINE option is set, any TCP urgent data received on
@@ -327,5 +339,5 @@ public interface SocketOptions {
* @see Socket#setOOBInline
* @see Socket#getOOBInline
*/
- @Native public final static int SO_OOBINLINE = 0x1003;
+ @Native public static final int SO_OOBINLINE = 0x1003;
}
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketOutputStream.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketOutputStream.java
index 9e8e7926e7..e8b23b11c0 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketOutputStream.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketOutputStream.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,8 +41,7 @@
* @author Jonathan Payne
* @author Arthur van Hoff
*/
-class SocketOutputStream extends FileOutputStream
-{
+class SocketOutputStream extends FileOutputStream {
// Android-removed: Android doesn't need to call native init.
// static {
// init();
@@ -116,10 +115,6 @@ private void socketWrite(byte b[], int off, int len) throws IOException {
BlockGuard.getThreadPolicy().onNetwork();
socketWrite0(fd, b, off, len);
} catch (SocketException se) {
- if (se instanceof sun.net.ConnectionResetException) {
- impl.setConnectionResetPending();
- se = new SocketException("Connection reset");
- }
if (impl.isClosedOrPending()) {
throw new SocketException("Socket closed");
} else {
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketPermission.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketPermission.java
index 2195eccd71..97346cd285 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketPermission.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketTimeoutException.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketTimeoutException.java
index 3b5b50a2e6..5daf600269 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketTimeoutException.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/SocketTimeoutException.java
@@ -48,14 +48,4 @@ public SocketTimeoutException(String msg) {
* Construct a new SocketTimeoutException with no detailed message.
*/
public SocketTimeoutException() {}
-
- /** @hide */
- public SocketTimeoutException(Throwable cause) {
- super(cause);
- }
-
- /** @hide */
- public SocketTimeoutException(String msg, Throwable cause) {
- super(msg, cause);
- }
}
diff --git a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/StandardSocketOptions.java b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/StandardSocketOptions.java
index 7fdd5f075d..ae47845fae 100644
--- a/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/StandardSocketOptions.java
+++ b/jre_emul/android/platform/libcore/ojluni/src/main/java/java/net/StandardSocketOptions.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -186,6 +186,29 @@ private StandardSocketOptions() { }
public static final SocketOption
- * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java }(2)
+ * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java} (2)
*
*
* against this result yields, in turn,
@@ -308,7 +309,7 @@
*
*
+ *
*
*
+ *
*
*
URL
represents a Uniform Resource
+ * Class {@code URL} represents a Uniform Resource
* Locator, a pointer to a "resource" on the World
* Wide Web. A resource can be something as simple as a file or a
* directory, or it can be a reference to a more complicated object,
* such as a query to a database or to a search engine. More
* information on the types of URLs and their formats can be found at:
- *
- *
- * http://www.socs.uts.edu.au/MosaicDocs-old/url-primer.html
- *
+ *
+ * Types of URL
* http
(HyperText Transfer Protocol) and that the
+ * In general, a URL can be broken into several parts. Consider the
+ * following example:
+ *
+ *
+ * http://www.example.com/docs/resource1.html
+ *
www.socs.uts.edu.au
. The information on that host
- * machine is named /MosaicDocs-old/url-primer.html
. The exact
+ * {@code www.example.com}. The information on that host
+ * machine is named {@code /docs/resource1.html}. The exact
* meaning of this name on the host machine is both protocol
* dependent and host dependent. The information normally resides in
* a file, but it could be generated on the fly. This component of
@@ -58,13 +74,13 @@
* port number to which the TCP connection is made on the remote host
* machine. If the port is not specified, the default port for
* the protocol is used instead. For example, the default port for
- * http
is 80
. An alternative port could be
+ * {@code http} is {@code 80}. An alternative port could be
* specified as:
*
*
- * http://www.socs.uts.edu.au:80/MosaicDocs-old/url-primer.html
+ * http://www.example.com:1080/docs/resource1.html
*
URL
is defined by RFC 2396: Uniform
* Resource Identifiers (URI): Generic Syntax, amended by RFC 2732: Format for
@@ -82,7 +98,7 @@
* This fragment is not technically part of the URL. Rather, it
* indicates that after the specified resource is retrieved, the
* application is specifically interested in that part of the
- * document that has the tag chapter1
attached to it. The
+ * document that has the tag {@code chapter1} attached to it. The
* meaning of a tag is resource specific.
* file
is
- * defined as path[?query]
+ * The specified file name on that host. {@code file} is
+ * defined as {@code path[?query]}
* @serial
*/
private String file;
@@ -205,48 +225,47 @@ public final class URL implements java.io.Serializable {
/* Our hash code.
* @serial
*/
- // ----- BEGIN android -----
- //private int hashCode = -1;
- private transient int hashCode = -1;
- // ----- END android -----
+ private int hashCode = -1;
+
+ private transient UrlDeserializedState tempState;
/**
- * Creates a URL
object from the specified
- * protocol
, host
, port
- * number, and file
.host
can be expressed as a host name or a literal
+ * {@code host} can be expressed as a host name or a literal
* IP address. If IPv6 literal address is used, it should be
- * enclosed in square brackets ('[' and ']'), as
+ * enclosed in square brackets ({@code '['} and {@code ']'}), as
* specified by RFC 2732;
* However, the literal IPv6 address format defined in RFC 2373: IP
* Version 6 Addressing Architecture is also accepted.port
number of -1
+ * Specifying a {@code port} number of {@code -1}
* indicates that the URL should use the default port for the
* protocol.URLStreamHandler
, is created for that protocol:
+ * class {@code URLStreamHandler}, is created for that protocol:
*
*
*
* URLStreamHandlerFactory
as the stream handler factory,
- * then the createURLStreamHandler
method of that instance
+ * {@code URLStreamHandlerFactory} as the stream handler factory,
+ * then the {@code createURLStreamHandler} method of that instance
* is called with the protocol string as an argument to create the
* stream protocol handler.
- * URLStreamHandlerFactory
has yet been set up,
- * or if the factory's createURLStreamHandler
method
- * returns null
, then the constructor finds the
+ *
- * If the value of that system property is not
* java.protocol.handler.pkgs
*
null
,
+ * If the value of that system property is not {@code null},
* it is interpreted as a list of packages separated by a vertical
- * slash character '|
'. The constructor tries to load
+ * slash character '{@code |}'. The constructor tries to load
* the class named:
*
* If this class does not exist, or if the class exists but it is not a
- * subclass of
* <package>.<protocol>.Handler
@@ -254,7 +273,7 @@ public final class URL implements java.io.Serializable {
* where <package> is replaced by the name of the package
* and <protocol> is replaced by the name of the protocol.
* If this class does not exist, or if the class exists but it is not
- * a subclass of
URLStreamHandler
, then the next package
+ * a subclass of {@code URLStreamHandler}, then the next package
* in the list is tried.
* URLStreamHandler
, then a
- * MalformedURLException
is thrown.
+ * subclass of {@code URLStreamHandler}, then a
+ * {@code MalformedURLException} is thrown.
*
* Protocol handlers for additional protocols may also be
* available.
@@ -295,13 +314,13 @@ public URL(String protocol, String host, int port, String file)
}
/**
- * Creates a URL from the specified
- * http, https, ftp, file, and jar
+ * http, https, file, and jar
*
protocol
- * name, host
name, and file
name. The
+ * Creates a URL from the specified {@code protocol}
+ * name, {@code host} name, and {@code file} name. The
* default port for the specified protocol is used.
* protocol
,
- * host
, -1
, and file
.
+ * constructor with the arguments being {@code protocol},
+ * {@code host}, {@code -1}, and {@code file}.
*
* No validation of the inputs is performed by this constructor.
*
@@ -318,21 +337,21 @@ public URL(String protocol, String host, String file)
}
/**
- * Creates a URL
object from the specified
- * protocol
, host
, port
- * number, file
, and handler
. Specifying
- * a port
number of -1
indicates that
+ * Creates a {@code URL} object from the specified
+ * {@code protocol}, {@code host}, {@code port}
+ * number, {@code file}, and {@code handler}. Specifying
+ * a {@code port} number of {@code -1} indicates that
* the URL should use the default port for the protocol. Specifying
- * a handler
of null
indicates that the URL
+ * a {@code handler} of {@code null} indicates that the URL
* should use a default stream handler for the protocol, as outlined
* for:
* java.net.URL#URL(java.lang.String, java.lang.String, int,
* java.lang.String)
*
* checkPermission
+ * the security manager's {@code checkPermission}
* method is called with a
- * NetPermission("specifyStreamHandler")
permission.
+ * {@code NetPermission("specifyStreamHandler")} permission.
* This may result in a SecurityException.
*
* No validation of the inputs is performed by this constructor.
@@ -345,7 +364,7 @@ public URL(String protocol, String host, String file)
* @exception MalformedURLException if an unknown protocol is specified.
* @exception SecurityException
* if a security manager exists and its
- * checkPermission
method doesn't allow
+ * {@code checkPermission} method doesn't allow
* specifying a stream handler explicitly.
* @see java.lang.System#getProperty(java.lang.String)
* @see java.net.URL#setURLStreamHandlerFactory(
@@ -388,6 +407,8 @@ public URL(String protocol, String host, int port, String file,
authority = (port == -1) ? host : host + ":" + port;
}
+ // Android-changed: App compat. Prepend '/' if host is null / empty
+ // Parts parts = new Parts(file);
Parts parts = new Parts(file, host);
path = parts.getPath();
query = parts.getQuery();
@@ -398,19 +419,28 @@ public URL(String protocol, String host, int port, String file,
this.file = path;
}
ref = parts.getRef();
+
+ /* J2Objc remove
+ // Note: we don't do validation of the URL here. Too risky to change
+ // right now, but worth considering for future reference. -br
+ if (handler == null &&
+ (handler = getURLStreamHandler(protocol)) == null) {
+ throw new MalformedURLException("unknown protocol: " + protocol);
+ }
+ */
this.handler = handler;
}
/**
- * Creates a URL
object from the String
+ * Creates a {@code URL} object from the {@code String}
* representation.
* null
first argument.
+ * constructor with a {@code null} first argument.
*
- * @param spec the String
to parse as a URL.
+ * @param spec the {@code String} to parse as a URL.
* @exception MalformedURLException if no protocol is specified, or an
- * unknown protocol is found, or spec is null.
+ * unknown protocol is found, or {@code spec} is {@code null}.
* @see java.net.URL#URL(java.net.URL, java.lang.String)
*/
public URL(String spec) throws MalformedURLException {
@@ -450,14 +480,14 @@ public URL(String spec) throws MalformedURLException {
* Otherwise, the path is treated as a relative path and is appended to the
* context path, as described in RFC2396. Also, in this case,
* the path is canonicalized through the removal of directory
- * changes made by occurences of ".." and ".".
+ * changes made by occurrences of ".." and ".".
* String
to parse as a URL.
+ * @param spec the {@code String} to parse as a URL.
* @exception MalformedURLException if no protocol is specified, or an
- * unknown protocol is found, or spec is null.
+ * unknown protocol is found, or {@code spec} is {@code null}.
* @see java.net.URL#URL(java.lang.String, java.lang.String,
* int, java.lang.String)
* @see java.net.URLStreamHandler
@@ -474,13 +504,13 @@ public URL(URL context, String spec) throws MalformedURLException {
* occurs as with the two argument constructor.
*
* @param context the context in which to parse the specification.
- * @param spec the String
to parse as a URL.
+ * @param spec the {@code String} to parse as a URL.
* @param handler the stream handler for the URL.
* @exception MalformedURLException if no protocol is specified, or an
- * unknown protocol is found, or spec is null.
+ * unknown protocol is found, or {@code spec} is {@code null}.
* @exception SecurityException
* if a security manager exists and its
- * checkPermission
method doesn't allow
+ * {@code checkPermission} method doesn't allow
* specifying a stream handler.
* @see java.net.URL#URL(java.lang.String, java.lang.String,
* int, java.lang.String)
@@ -492,10 +522,150 @@ public URL(URL context, String spec) throws MalformedURLException {
public URL(URL context, String spec, Object handler)
throws MalformedURLException
{
- getDelegate().initURL(this, context, spec, handler);
+ getDelegate().initURL(this, context, spec, handler);
+ /* J2ObjC: disabled
+ String original = spec;
+ int i, limit, c;
+ int start = 0;
+ String newProtocol = null;
+ boolean aRef=false;
+ boolean isRelative = false;
+
+ // Check for permission to specify a handler
+ if (handler != null) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ checkSpecifyHandler(sm);
+ }
+ }
+
+ try {
+ limit = spec.length();
+ while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) {
+ limit--; //eliminate trailing whitespace
+ }
+ while ((start < limit) && (spec.charAt(start) <= ' ')) {
+ start++; // eliminate leading whitespace
+ }
+
+ if (spec.regionMatches(true, start, "url:", 0, 4)) {
+ start += 4;
+ }
+ if (start < spec.length() && spec.charAt(start) == '#') {
+ / we're assuming this is a ref relative to the context URL.
+ * This means protocols cannot start w/ '#', but we must parse
+ * ref URL's like: "hello:there" w/ a ':' in them.
+ /
+ aRef=true;
+ }
+ for (i = start ; !aRef && (i < limit) &&
+ ((c = spec.charAt(i)) != '/') ; i++) {
+ if (c == ':') {
+
+ String s = spec.substring(start, i).toLowerCase();
+ if (isValidProtocol(s)) {
+ newProtocol = s;
+ start = i + 1;
+ }
+ break;
+ }
+ }
+
+ // Only use our context if the protocols match.
+ protocol = newProtocol;
+ if ((context != null) && ((newProtocol == null) ||
+ newProtocol.equalsIgnoreCase(context.protocol))) {
+ // inherit the protocol handler from the context
+ // if not specified to the constructor
+ if (handler == null) {
+ handler = context.handler;
+ }
+
+ // If the context is a hierarchical URL scheme and the spec
+ // contains a matching scheme then maintain backwards
+ // compatibility and treat it as if the spec didn't contain
+ // the scheme; see 5.2.3 of RFC2396
+ if (context.path != null && context.path.startsWith("/"))
+ newProtocol = null;
+
+ if (newProtocol == null) {
+ protocol = context.protocol;
+ authority = context.authority;
+ userInfo = context.userInfo;
+ host = context.host;
+ port = context.port;
+ file = context.file;
+ path = context.path;
+ isRelative = true;
+ }
+ }
+
+ if (protocol == null) {
+ throw new MalformedURLException("no protocol: "+original);
+ }
+
+ // Get the protocol handler if not specified or the protocol
+ // of the context could not be used
+ if (handler == null &&
+ (handler = getURLStreamHandler(protocol)) == null) {
+ throw new MalformedURLException("unknown protocol: "+protocol);
+ }
+
+ this.handler = handler;
+
+ i = spec.indexOf('#', start);
+ if (i >= 0) {
+ ref = spec.substring(i + 1, limit);
+ limit = i;
+ }
+
+ /
+ * Handle special case inheritance of query and fragment
+ * implied by RFC2396 section 5.2.2.
+ /
+ if (isRelative && start == limit) {
+ query = context.query;
+ if (ref == null) {
+ ref = context.ref;
+ }
+ }
+
+ handler.parseURL(this, spec, start, limit);
+
+ } catch(MalformedURLException e) {
+ throw e;
+ } catch(Exception e) {
+ MalformedURLException exception = new MalformedURLException(e.getMessage());
+ exception.initCause(e);
+ throw exception;
+ }
+ */
+ }
+
+ /*
+ * J2ObjC: disabled
+ * Returns true if specified string is a valid protocol name.
+
+ private boolean isValidProtocol(String protocol) {
+ int len = protocol.length();
+ if (len < 1)
+ return false;
+ char c = protocol.charAt(0);
+ if (!Character.isLetter(c))
+ return false;
+ for (int i = 1; i < len; i++) {
+ c = protocol.charAt(i);
+ if (!Character.isLetterOrDigit(c) && c != '.' && c != '+' &&
+ c != '-') {
+ return false;
+ }
+ }
+ return true;
}
+ */
- /* J2ObjC: disabled.
+ /*
+ * J2ObjC: disabled
* Checks for permission to specify a stream handler.
private void checkSpecifyHandler(SecurityManager sm) {
sm.checkPermission(SecurityConstants.SPECIFY_HANDLER_PERMISSION);
@@ -551,12 +721,14 @@ protected void set(String protocol, String host,
* @since 1.3
*/
protected void set(String protocol, String host, int port,
- String authority, String userInfo, String path,
- String query, String ref) {
+ String authority, String userInfo, String path,
+ String query, String ref) {
synchronized (this) {
this.protocol = protocol;
this.host = host;
this.port = port;
+ // Android-changed: App compat. Only include query part if it's nonempty.
+ // this.file = query == null ? path : path + "?" + query;
this.file = (query == null || query.isEmpty()) ? path : path + "?" + query;
this.userInfo = userInfo;
this.path = path;
@@ -570,14 +742,15 @@ protected void set(String protocol, String host, int port,
}
}
+ /* J2ObjC: added */
void setURLHandler(Object handler) {
this.handler = handler;
}
/**
- * Gets the query part of this URL
.
+ * Gets the query part of this {@code URL}.
*
- * @return the query part of this URL
,
+ * @return the query part of this {@code URL},
* or null
if one does not exist
* @since 1.3
*/
@@ -586,9 +759,9 @@ public String getQuery() {
}
/**
- * Gets the path part of this URL
.
+ * Gets the path part of this {@code URL}.
*
- * @return the path part of this URL
, or an
+ * @return the path part of this {@code URL}, or an
* empty string if one does not exist
* @since 1.3
*/
@@ -597,9 +770,9 @@ public String getPath() {
}
/**
- * Gets the userInfo part of this URL
.
+ * Gets the userInfo part of this {@code URL}.
*
- * @return the userInfo part of this URL
, or
+ * @return the userInfo part of this {@code URL}, or
* null
if one does not exist
* @since 1.3
*/
@@ -608,9 +781,9 @@ public String getUserInfo() {
}
/**
- * Gets the authority part of this URL
.
+ * Gets the authority part of this {@code URL}.
*
- * @return the authority part of this URL
+ * @return the authority part of this {@code URL}
* @since 1.3
*/
public String getAuthority() {
@@ -618,7 +791,7 @@ public String getAuthority() {
}
/**
- * Gets the port number of this URL
.
+ * Gets the port number of this {@code URL}.
*
* @return the port number, or -1 if the port is not set
*/
@@ -628,7 +801,7 @@ public int getPort() {
/**
* Gets the default port number of the protocol associated
- * with this URL
. If the URL scheme or the URLStreamHandler
+ * with this {@code URL}. If the URL scheme or the URLStreamHandler
* for the URL do not define a default port number,
* then -1 is returned.
*
@@ -636,6 +809,7 @@ public int getPort() {
* @since 1.4
*/
public int getDefaultPort() {
+ /* J2ObjC: modified */
try {
return getDelegate().getDefaultPort(this);
} catch (MalformedURLException e) {
@@ -644,35 +818,35 @@ public int getDefaultPort() {
}
/**
- * Gets the protocol name of this URL
.
+ * Gets the protocol name of this {@code URL}.
*
- * @return the protocol of this URL
.
+ * @return the protocol of this {@code URL}.
*/
public String getProtocol() {
return protocol;
}
/**
- * Gets the host name of this URL
, if applicable.
+ * Gets the host name of this {@code URL}, if applicable.
* The format of the host conforms to RFC 2732, i.e. for a
* literal IPv6 address, this method will return the IPv6 address
- * enclosed in square brackets ('[' and ']').
+ * enclosed in square brackets ({@code '['} and {@code ']'}).
*
- * @return the host name of this URL
.
+ * @return the host name of this {@code URL}.
*/
public String getHost() {
return host;
}
/**
- * Gets the file name of this URL
.
+ * Gets the file name of this {@code URL}.
* The returned file portion will be
* the same as getPath()
, plus the concatenation of
* the value of getQuery()
, if any. If there is
* no query portion, this method and getPath()
will
* return identical results.
*
- * @return the file name of this URL
,
+ * @return the file name of this {@code URL},
* or an empty string if one does not exist
*/
public String getFile() {
@@ -681,20 +855,21 @@ public String getFile() {
/**
* Gets the anchor (also known as the "reference") of this
- * URL
.
+ * {@code URL}.
*
* @return the anchor (also known as the "reference") of this
- * URL
, or null
if one does not exist
+ * {@code URL}, or null
if one does not exist
*/
public String getRef() {
return ref;
}
+ // Android-changed: Don't let URL.equals() attempt to resolve host names.
/**
* Compares this URL for equality with another object.false
.true
if the objects are the same;
- * false
otherwise.
+ * @return {@code true} if the objects are the same;
+ * {@code false} otherwise.
*/
public boolean equals(Object obj) {
if (!(obj instanceof URL))
return false;
URL u2 = (URL)obj;
-
+ // J2ObjC: modified
try {
return getDelegate().equals(this, u2);
} catch (MalformedURLException e) {
@@ -749,12 +924,12 @@ public boolean equals(Object obj) {
* The hash code is based upon all the URL components relevant for URL
* comparison. As such, this operation is a blocking operation.URL
.
+ * @return a hash code for this {@code URL}.
*/
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
-
+ // J2ObjC: modified
try {
hashCode = getDelegate().hashCode(this);
} catch (MalformedURLException e) {
@@ -766,15 +941,16 @@ public synchronized int hashCode() {
/**
* Compares two URLs, excluding the fragment component.true
if this URL
and the
- * other
argument are equal without taking the
+ * Returns {@code true} if this {@code URL} and the
+ * {@code other} argument are equal without taking the
* fragment component into consideration.
*
- * @param other the URL
to compare against.
- * @return true
if they reference the same remote object;
- * false
otherwise.
+ * @param other the {@code URL} to compare against.
+ * @return {@code true} if they reference the same remote object;
+ * {@code false} otherwise.
*/
public boolean sameFile(URL other) {
+ // J2ObjC: modified
try {
return getDelegate().sameFile(this, other);
} catch (MalformedURLException e) {
@@ -783,8 +959,8 @@ public boolean sameFile(URL other) {
}
/**
- * Constructs a string representation of this URL
. The
- * string is created by calling the toExternalForm
+ * Constructs a string representation of this {@code URL}. The
+ * string is created by calling the {@code toExternalForm}
* method of the stream protocol handler for this object.
*
* @return a string representation of this object.
@@ -797,8 +973,8 @@ public String toString() {
}
/**
- * Constructs a string representation of this URL
. The
- * string is created by calling the toExternalForm
+ * Constructs a string representation of this {@code URL}. The
+ * string is created by calling the {@code toExternalForm}
* method of the stream protocol handler for this object.
*
* @return a string representation of this object.
@@ -807,6 +983,7 @@ public String toString() {
* @see java.net.URLStreamHandler#toExternalForm(java.net.URL)
*/
public String toExternalForm() {
+ // J2ObjC: modified
try {
return getDelegate().toExternalForm(this);
} catch (MalformedURLException e) {
@@ -816,7 +993,7 @@ public String toExternalForm() {
/**
* Returns a {@link java.net.URI} equivalent to this URL.
- * This method functions in the same way as new URI (this.toString())
.
+ * This method functions in the same way as {@code new URI (this.toString())}.
* URLConnection
to the URL.
+ * @return a {@code URLConnection} to the URL.
* @exception IOException if an I/O exception occurs.
* @exception SecurityException if a security manager is present
* and the caller doesn't have permission to connect
@@ -895,12 +1073,13 @@ public URLConnection openConnection() throws java.io.IOException {
*/
@ObjectiveCName("openConnectionWithJavaNetProxy:")
public URLConnection openConnection(Object proxy) throws java.io.IOException {
+ // J2ObjC: modified
return getDelegate().openConnection(this, proxy);
}
/**
- * Opens a connection to this URL
and returns an
- * InputStream
for reading from that connection. This
+ * Opens a connection to this {@code URL} and returns an
+ * {@code InputStream} for reading from that connection. This
* method is a shorthand for:
*
* openConnection().getInputStream()
@@ -943,14 +1122,74 @@ public final Object getContent() throws java.io.IOException {
* @see java.net.URLConnection#getContent(Class[])
* @since 1.3
*/
- public final Object getContent(Class>[] classes)
+ public final Object getContent(Class[] classes)
throws java.io.IOException {
return openConnection().getContent(classes);
}
+ /*
+ * J2ObjC: removed
+ * The URLStreamHandler factory.
+ */
+ static URLStreamHandlerFactory factory;
+
+ /**
+ * Sets an application's {@code URLStreamHandlerFactory}.
+ * This method can be called at most once in a given Java Virtual
+ * Machine.
+ *
+ *