mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
Merge
This commit is contained in:
commit
1b03f22dff
272 changed files with 7154 additions and 1904 deletions
|
@ -75,7 +75,7 @@ import static java.util.function.Predicate.not;
|
|||
* System.out.println("abc");
|
||||
* String cde = "cde";
|
||||
* System.out.println("abc" + cde);
|
||||
* String c = "abc".substring(2,3);
|
||||
* String c = "abc".substring(2, 3);
|
||||
* String d = cde.substring(1, 2);
|
||||
* </pre></blockquote>
|
||||
* <p>
|
||||
|
@ -2160,27 +2160,48 @@ public final class String
|
|||
* @since 1.5
|
||||
*/
|
||||
public String replace(CharSequence target, CharSequence replacement) {
|
||||
String tgtStr = target.toString();
|
||||
String trgtStr = target.toString();
|
||||
String replStr = replacement.toString();
|
||||
int j = indexOf(tgtStr);
|
||||
if (j < 0) {
|
||||
return this;
|
||||
}
|
||||
int tgtLen = tgtStr.length();
|
||||
int tgtLen1 = Math.max(tgtLen, 1);
|
||||
int thisLen = length();
|
||||
int trgtLen = trgtStr.length();
|
||||
int replLen = replStr.length();
|
||||
|
||||
int newLenHint = thisLen - tgtLen + replStr.length();
|
||||
if (newLenHint < 0) {
|
||||
throw new OutOfMemoryError();
|
||||
if (trgtLen > 0) {
|
||||
if (trgtLen == 1 && replLen == 1) {
|
||||
return replace(trgtStr.charAt(0), replStr.charAt(0));
|
||||
}
|
||||
|
||||
boolean thisIsLatin1 = this.isLatin1();
|
||||
boolean trgtIsLatin1 = trgtStr.isLatin1();
|
||||
boolean replIsLatin1 = replStr.isLatin1();
|
||||
String ret = (thisIsLatin1 && trgtIsLatin1 && replIsLatin1)
|
||||
? StringLatin1.replace(value, thisLen,
|
||||
trgtStr.value, trgtLen,
|
||||
replStr.value, replLen)
|
||||
: StringUTF16.replace(value, thisLen, thisIsLatin1,
|
||||
trgtStr.value, trgtLen, trgtIsLatin1,
|
||||
replStr.value, replLen, replIsLatin1);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
return this;
|
||||
|
||||
} else { // trgtLen == 0
|
||||
int resultLen;
|
||||
try {
|
||||
resultLen = Math.addExact(thisLen, Math.multiplyExact(
|
||||
Math.addExact(thisLen, 1), replLen));
|
||||
} catch (ArithmeticException ignored) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(resultLen);
|
||||
sb.append(replStr);
|
||||
for (int i = 0; i < thisLen; ++i) {
|
||||
sb.append(charAt(i)).append(replStr);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(newLenHint);
|
||||
int i = 0;
|
||||
do {
|
||||
sb.append(this, i, j).append(replStr);
|
||||
i = j + tgtLen;
|
||||
} while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
|
||||
return sb.append(this, i, thisLen).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, 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
|
||||
|
@ -42,6 +42,14 @@ import static java.lang.String.checkOffset;
|
|||
|
||||
final class StringLatin1 {
|
||||
|
||||
/**
|
||||
* The maximum size of array to allocate (unless necessary).
|
||||
* Some VMs reserve some header words in an array.
|
||||
* Attempts to allocate larger arrays may result in
|
||||
* OutOfMemoryError: Requested array size exceeds VM limit
|
||||
*/
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
public static char charAt(byte[] value, int index) {
|
||||
if (index < 0 || index >= value.length) {
|
||||
throw new StringIndexOutOfBoundsException(index);
|
||||
|
@ -304,7 +312,7 @@ final class StringLatin1 {
|
|||
}
|
||||
if (i < len) {
|
||||
if (canEncode(newChar)) {
|
||||
byte buf[] = new byte[len];
|
||||
byte[] buf = StringConcatHelper.newArray(len);
|
||||
for (int j = 0; j < i; j++) { // TBD arraycopy?
|
||||
buf[j] = value[j];
|
||||
}
|
||||
|
@ -330,6 +338,64 @@ final class StringLatin1 {
|
|||
return null; // for string to return this;
|
||||
}
|
||||
|
||||
public static String replace(byte[] value, int valLen, byte[] targ,
|
||||
int targLen, byte[] repl, int replLen)
|
||||
{
|
||||
assert targLen > 0;
|
||||
int i, j, p = 0;
|
||||
if (valLen == 0 || (i = indexOf(value, valLen, targ, targLen, 0)) < 0) {
|
||||
return null; // for string to return this;
|
||||
}
|
||||
|
||||
// find and store indices of substrings to replace
|
||||
int[] pos = new int[16];
|
||||
pos[0] = i;
|
||||
i += targLen;
|
||||
while ((j = indexOf(value, valLen, targ, targLen, i)) > 0) {
|
||||
if (++p == pos.length) {
|
||||
int cap = p + (p >> 1);
|
||||
// overflow-conscious code
|
||||
if (cap - MAX_ARRAY_SIZE > 0) {
|
||||
if (p == MAX_ARRAY_SIZE) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
cap = MAX_ARRAY_SIZE;
|
||||
}
|
||||
pos = Arrays.copyOf(pos, cap);
|
||||
}
|
||||
pos[p] = j;
|
||||
i = j + targLen;
|
||||
}
|
||||
|
||||
int resultLen;
|
||||
try {
|
||||
resultLen = Math.addExact(valLen,
|
||||
Math.multiplyExact(++p, replLen - targLen));
|
||||
} catch (ArithmeticException ignored) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
if (resultLen == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] result = StringConcatHelper.newArray(resultLen);
|
||||
int posFrom = 0, posTo = 0;
|
||||
for (int q = 0; q < p; ++q) {
|
||||
int nextPos = pos[q];
|
||||
while (posFrom < nextPos) {
|
||||
result[posTo++] = value[posFrom++];
|
||||
}
|
||||
posFrom += targLen;
|
||||
for (int k = 0; k < replLen; ++k) {
|
||||
result[posTo++] = repl[k];
|
||||
}
|
||||
}
|
||||
while (posFrom < valLen) {
|
||||
result[posTo++] = value[posFrom++];
|
||||
}
|
||||
return new String(result, LATIN1);
|
||||
}
|
||||
|
||||
// case insensitive
|
||||
public static boolean regionMatchesCI(byte[] value, int toffset,
|
||||
byte[] other, int ooffset, int len) {
|
||||
|
|
|
@ -574,7 +574,7 @@ final class StringUTF16 {
|
|||
}
|
||||
}
|
||||
if (i < len) {
|
||||
byte buf[] = new byte[value.length];
|
||||
byte[] buf = new byte[value.length];
|
||||
for (int j = 0; j < i; j++) {
|
||||
putChar(buf, j, getChar(value, j)); // TBD:arraycopy?
|
||||
}
|
||||
|
@ -582,21 +582,145 @@ final class StringUTF16 {
|
|||
char c = getChar(value, i);
|
||||
putChar(buf, i, c == oldChar ? newChar : c);
|
||||
i++;
|
||||
}
|
||||
// Check if we should try to compress to latin1
|
||||
if (String.COMPACT_STRINGS &&
|
||||
!StringLatin1.canEncode(oldChar) &&
|
||||
StringLatin1.canEncode(newChar)) {
|
||||
byte[] val = compress(buf, 0, len);
|
||||
if (val != null) {
|
||||
return new String(val, LATIN1);
|
||||
}
|
||||
}
|
||||
return new String(buf, UTF16);
|
||||
}
|
||||
// Check if we should try to compress to latin1
|
||||
if (String.COMPACT_STRINGS &&
|
||||
!StringLatin1.canEncode(oldChar) &&
|
||||
StringLatin1.canEncode(newChar)) {
|
||||
byte[] val = compress(buf, 0, len);
|
||||
if (val != null) {
|
||||
return new String(val, LATIN1);
|
||||
}
|
||||
}
|
||||
return new String(buf, UTF16);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String replace(byte[] value, int valLen, boolean valLat1,
|
||||
byte[] targ, int targLen, boolean targLat1,
|
||||
byte[] repl, int replLen, boolean replLat1)
|
||||
{
|
||||
assert targLen > 0;
|
||||
assert !valLat1 || !targLat1 || !replLat1;
|
||||
|
||||
// Possible combinations of the arguments/result encodings:
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | # | VALUE | TARGET | REPL | RESULT |
|
||||
// +===+========+========+========+=======================+
|
||||
// | 1 | Latin1 | Latin1 | UTF16 | null or UTF16 |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | 2 | Latin1 | UTF16 | Latin1 | null |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | 3 | Latin1 | UTF16 | UTF16 | null |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | 4 | UTF16 | Latin1 | Latin1 | null or UTF16 |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | 5 | UTF16 | Latin1 | UTF16 | null or UTF16 |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | 6 | UTF16 | UTF16 | Latin1 | null, Latin1 or UTF16 |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
// | 7 | UTF16 | UTF16 | UTF16 | null or UTF16 |
|
||||
// +---+--------+--------+--------+-----------------------+
|
||||
|
||||
if (String.COMPACT_STRINGS && valLat1 && !targLat1) {
|
||||
// combinations 2 or 3
|
||||
return null; // for string to return this;
|
||||
}
|
||||
|
||||
int i = (String.COMPACT_STRINGS && valLat1)
|
||||
? StringLatin1.indexOf(value, targ) :
|
||||
(String.COMPACT_STRINGS && targLat1)
|
||||
? indexOfLatin1(value, targ)
|
||||
: indexOf(value, targ);
|
||||
if (i < 0) {
|
||||
return null; // for string to return this;
|
||||
}
|
||||
|
||||
// find and store indices of substrings to replace
|
||||
int j, p = 0;
|
||||
int[] pos = new int[16];
|
||||
pos[0] = i;
|
||||
i += targLen;
|
||||
while ((j = ((String.COMPACT_STRINGS && valLat1)
|
||||
? StringLatin1.indexOf(value, valLen, targ, targLen, i) :
|
||||
(String.COMPACT_STRINGS && targLat1)
|
||||
? indexOfLatin1(value, valLen, targ, targLen, i)
|
||||
: indexOf(value, valLen, targ, targLen, i))) > 0)
|
||||
{
|
||||
if (++p == pos.length) {
|
||||
int cap = p + (p >> 1);
|
||||
// overflow-conscious code
|
||||
if (cap - MAX_ARRAY_SIZE > 0) {
|
||||
if (p == MAX_ARRAY_SIZE) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
cap = MAX_ARRAY_SIZE;
|
||||
}
|
||||
pos = Arrays.copyOf(pos, cap);
|
||||
}
|
||||
pos[p] = j;
|
||||
i = j + targLen;
|
||||
}
|
||||
|
||||
int resultLen;
|
||||
try {
|
||||
resultLen = Math.addExact(valLen,
|
||||
Math.multiplyExact(++p, replLen - targLen));
|
||||
} catch (ArithmeticException ignored) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
if (resultLen == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
byte[] result = newBytesFor(resultLen);
|
||||
int posFrom = 0, posTo = 0;
|
||||
for (int q = 0; q < p; ++q) {
|
||||
int nextPos = pos[q];
|
||||
if (String.COMPACT_STRINGS && valLat1) {
|
||||
while (posFrom < nextPos) {
|
||||
char c = (char)(value[posFrom++] & 0xff);
|
||||
putChar(result, posTo++, c);
|
||||
}
|
||||
} else {
|
||||
while (posFrom < nextPos) {
|
||||
putChar(result, posTo++, getChar(value, posFrom++));
|
||||
}
|
||||
}
|
||||
posFrom += targLen;
|
||||
if (String.COMPACT_STRINGS && replLat1) {
|
||||
for (int k = 0; k < replLen; ++k) {
|
||||
char c = (char)(repl[k] & 0xff);
|
||||
putChar(result, posTo++, c);
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < replLen; ++k) {
|
||||
putChar(result, posTo++, getChar(repl, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (String.COMPACT_STRINGS && valLat1) {
|
||||
while (posFrom < valLen) {
|
||||
char c = (char)(value[posFrom++] & 0xff);
|
||||
putChar(result, posTo++, c);
|
||||
}
|
||||
} else {
|
||||
while (posFrom < valLen) {
|
||||
putChar(result, posTo++, getChar(value, posFrom++));
|
||||
}
|
||||
}
|
||||
|
||||
if (String.COMPACT_STRINGS && replLat1 && !targLat1) {
|
||||
// combination 6
|
||||
byte[] lat1Result = compress(result, 0, resultLen);
|
||||
if (lat1Result != null) {
|
||||
return new String(lat1Result, LATIN1);
|
||||
}
|
||||
}
|
||||
return new String(result, UTF16);
|
||||
}
|
||||
|
||||
public static boolean regionMatchesCI(byte[] value, int toffset,
|
||||
byte[] other, int ooffset, int len) {
|
||||
int last = toffset + len;
|
||||
|
@ -1430,6 +1554,15 @@ final class StringUTF16 {
|
|||
|
||||
static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
|
||||
|
||||
|
||||
/**
|
||||
* The maximum size of array to allocate (unless necessary).
|
||||
* Some VMs reserve some header words in an array.
|
||||
* Attempts to allocate larger arrays may result in
|
||||
* OutOfMemoryError: Requested array size exceeds VM limit
|
||||
*/
|
||||
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
// Used by trusted callers. Assumes all necessary bounds checks have
|
||||
// been done by the caller.
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ public interface ClassDesc
|
|||
* @param moreNestedNames the unqualified name(s) of the remaining levels of
|
||||
* nested class
|
||||
* @return a {@linkplain ClassDesc} describing the nested class
|
||||
* @throws NullPointerException if any argument is {@code null}
|
||||
* @throws NullPointerException if any argument or its contents is {@code null}
|
||||
* @throws IllegalStateException if this {@linkplain ClassDesc} does not
|
||||
* describe a class or interface type
|
||||
* @throws IllegalArgumentException if the nested class name is invalid
|
||||
|
@ -221,6 +221,11 @@ public interface ClassDesc
|
|||
default ClassDesc nested(String firstNestedName, String... moreNestedNames) {
|
||||
if (!isClassOrInterface())
|
||||
throw new IllegalStateException("Outer class is not a class or interface type");
|
||||
validateMemberName(firstNestedName, false);
|
||||
requireNonNull(moreNestedNames);
|
||||
for (String addNestedNames : moreNestedNames) {
|
||||
validateMemberName(addNestedNames, false);
|
||||
}
|
||||
return moreNestedNames.length == 0
|
||||
? nested(firstNestedName)
|
||||
: nested(firstNestedName + Stream.of(moreNestedNames).collect(joining("$", "$", "")));
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.Collections;
|
||||
|
||||
|
@ -81,6 +82,7 @@ class ServerSocket implements java.io.Closeable {
|
|||
* @since 12
|
||||
*/
|
||||
protected ServerSocket(SocketImpl impl) {
|
||||
Objects.requireNonNull(impl);
|
||||
this.impl = impl;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 2019, 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
|
||||
|
@ -1403,8 +1403,9 @@ public final class URL implements java.io.Serializable {
|
|||
|
||||
URLStreamHandlerFactory fac;
|
||||
boolean checkedWithFactory = false;
|
||||
boolean overrideableProtocol = isOverrideable(protocol);
|
||||
|
||||
if (isOverrideable(protocol) && jdk.internal.misc.VM.isBooted()) {
|
||||
if (overrideableProtocol && jdk.internal.misc.VM.isBooted()) {
|
||||
// Use the factory (if any). Volatile read makes
|
||||
// URLStreamHandlerFactory appear fully initialized to current thread.
|
||||
fac = factory;
|
||||
|
@ -1440,7 +1441,8 @@ public final class URL implements java.io.Serializable {
|
|||
|
||||
// Check with factory if another thread set a
|
||||
// factory since our last check
|
||||
if (!checkedWithFactory && (fac = factory) != null) {
|
||||
if (overrideableProtocol && !checkedWithFactory &&
|
||||
(fac = factory) != null) {
|
||||
handler2 = fac.createURLStreamHandler(protocol);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2019, 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
|
||||
|
@ -252,10 +252,8 @@ public final class FileSystems {
|
|||
* Suppose there is a provider identified by the scheme {@code "memory"}
|
||||
* installed:
|
||||
* <pre>
|
||||
* Map<String,String> env = new HashMap<>();
|
||||
* env.put("capacity", "16G");
|
||||
* env.put("blockSize", "4k");
|
||||
* FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
|
||||
* FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"),
|
||||
* Map.of("capacity", "16G", "blockSize", "4k"));
|
||||
* </pre>
|
||||
*
|
||||
* @param uri
|
||||
|
@ -365,14 +363,13 @@ public final class FileSystems {
|
|||
* systems where the contents of one or more files is treated as a file
|
||||
* system.
|
||||
*
|
||||
* <p> This method iterates over the {@link FileSystemProvider#installedProviders()
|
||||
* installed} providers. It invokes, in turn, each provider's {@link
|
||||
* FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
|
||||
* with an empty map. If a provider returns a file system then the iteration
|
||||
* terminates and the file system is returned. If none of the installed
|
||||
* providers return a {@code FileSystem} then an attempt is made to locate
|
||||
* the provider using the given class loader. If a provider returns a file
|
||||
* system then the lookup terminates and the file system is returned.
|
||||
* <p> This method first attempts to locate an installed provider in exactly
|
||||
* the same manner as the {@link #newFileSystem(Path, Map, ClassLoader)
|
||||
* newFileSystem(Path, Map, ClassLoader)} method with an empty map. If none
|
||||
* of the installed providers return a {@code FileSystem} then an attempt is
|
||||
* made to locate the provider using the given class loader. If a provider
|
||||
* returns a file system then the lookup terminates and the file system is
|
||||
* returned.
|
||||
*
|
||||
* @param path
|
||||
* the path to the file
|
||||
|
@ -395,11 +392,132 @@ public final class FileSystems {
|
|||
public static FileSystem newFileSystem(Path path,
|
||||
ClassLoader loader)
|
||||
throws IOException
|
||||
{
|
||||
return newFileSystem(path, Map.of(), loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FileSystem} to access the contents of a file as a
|
||||
* file system.
|
||||
*
|
||||
* <p> This method makes use of specialized providers that create pseudo file
|
||||
* systems where the contents of one or more files is treated as a file
|
||||
* system.
|
||||
*
|
||||
* <p> This method first attempts to locate an installed provider in exactly
|
||||
* the same manner as the {@link #newFileSystem(Path,Map,ClassLoader)
|
||||
* newFileSystem(Path, Map, ClassLoader)} method. If found, the provider's
|
||||
* {@link FileSystemProvider#newFileSystem(Path, Map) newFileSystem(Path, Map)}
|
||||
* method is invoked to construct the new file system.
|
||||
*
|
||||
* @param path
|
||||
* the path to the file
|
||||
* @param env
|
||||
* a map of provider specific properties to configure the file system;
|
||||
* may be empty
|
||||
*
|
||||
* @return a new file system
|
||||
*
|
||||
* @throws ProviderNotFoundException
|
||||
* if a provider supporting this file type cannot be located
|
||||
* @throws ServiceConfigurationError
|
||||
* when an error occurs while loading a service provider
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
* @throws SecurityException
|
||||
* if a security manager is installed and it denies an unspecified
|
||||
* permission
|
||||
*
|
||||
* @since 13
|
||||
*/
|
||||
public static FileSystem newFileSystem(Path path, Map<String,?> env)
|
||||
throws IOException
|
||||
{
|
||||
return newFileSystem(path, env, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FileSystem} to access the contents of a file as a
|
||||
* file system.
|
||||
*
|
||||
* <p> This method makes use of specialized providers that create pseudo file
|
||||
* systems where the contents of one or more files is treated as a file
|
||||
* system.
|
||||
*
|
||||
* <p> This method first attempts to locate an installed provider in exactly
|
||||
* the same manner as the {@link #newFileSystem(Path,Map,ClassLoader)
|
||||
* newFileSystem(Path, Map, ClassLoader)} method. If found, the provider's
|
||||
* {@link FileSystemProvider#newFileSystem(Path, Map) newFileSystem(Path, Map)}
|
||||
* method is invoked with an empty map to construct the new file system.
|
||||
*
|
||||
* @param path
|
||||
* the path to the file
|
||||
*
|
||||
* @return a new file system
|
||||
*
|
||||
* @throws ProviderNotFoundException
|
||||
* if a provider supporting this file type cannot be located
|
||||
* @throws ServiceConfigurationError
|
||||
* when an error occurs while loading a service provider
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
* @throws SecurityException
|
||||
* if a security manager is installed and it denies an unspecified
|
||||
* permission
|
||||
*
|
||||
* @since 13
|
||||
*/
|
||||
public static FileSystem newFileSystem(Path path) throws IOException {
|
||||
return newFileSystem(path, Map.of(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FileSystem} to access the contents of a file as a
|
||||
* file system.
|
||||
*
|
||||
* <p> This method makes use of specialized providers that create pseudo file
|
||||
* systems where the contents of one or more files is treated as a file
|
||||
* system.
|
||||
*
|
||||
* <p> This method iterates over the {@link FileSystemProvider#installedProviders()
|
||||
* installed} providers. It invokes, in turn, each provider's {@link
|
||||
* FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)}
|
||||
* method. If a provider returns a file system then the iteration
|
||||
* terminates and the file system is returned.
|
||||
* If none of the installed providers return a {@code FileSystem} then
|
||||
* an attempt is made to locate the provider using the given class loader.
|
||||
* If a provider returns a file
|
||||
* system, then the lookup terminates and the file system is returned.
|
||||
*
|
||||
* @param path
|
||||
* the path to the file
|
||||
* @param env
|
||||
* a map of provider specific properties to configure the file system;
|
||||
* may be empty
|
||||
* @param loader
|
||||
* the class loader to locate the provider or {@code null} to only
|
||||
* attempt to locate an installed provider
|
||||
*
|
||||
* @return a new file system
|
||||
*
|
||||
* @throws ProviderNotFoundException
|
||||
* if a provider supporting this file type cannot be located
|
||||
* @throws ServiceConfigurationError
|
||||
* when an error occurs while loading a service provider
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
* @throws SecurityException
|
||||
* if a security manager is installed and it denies an unspecified
|
||||
* permission
|
||||
*
|
||||
* @since 13
|
||||
*/
|
||||
public static FileSystem newFileSystem(Path path, Map<String,?> env,
|
||||
ClassLoader loader)
|
||||
throws IOException
|
||||
{
|
||||
if (path == null)
|
||||
throw new NullPointerException();
|
||||
Map<String,?> env = Collections.emptyMap();
|
||||
|
||||
// check installed providers
|
||||
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
|
||||
try {
|
||||
|
|
|
@ -62,10 +62,11 @@ public final class Objects {
|
|||
* Returns {@code true} if the arguments are equal to each other
|
||||
* and {@code false} otherwise.
|
||||
* Consequently, if both arguments are {@code null}, {@code true}
|
||||
* is returned and if exactly one argument is {@code null}, {@code
|
||||
* false} is returned. Otherwise, equality is determined by using
|
||||
* the {@link Object#equals equals} method of the first
|
||||
* argument.
|
||||
* is returned. Otherwise, if the first argument is not {@code
|
||||
* null}, equality is determined by calling the {@link
|
||||
* Object#equals equals} method of the first argument with the
|
||||
* second argument of this method. Otherwise, {@code false} is
|
||||
* returned.
|
||||
*
|
||||
* @param a an object
|
||||
* @param b an object to be compared with {@code a} for equality
|
||||
|
|
|
@ -1678,7 +1678,13 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
|
|||
return;
|
||||
int j = i;
|
||||
i += 2;
|
||||
int[] newtemp = new int[j + 3*(pLen-i) + 2];
|
||||
int newTempLen;
|
||||
try {
|
||||
newTempLen = Math.addExact(j + 2, Math.multiplyExact(3, pLen - i));
|
||||
} catch (ArithmeticException ae) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
int[] newtemp = new int[newTempLen];
|
||||
System.arraycopy(temp, 0, newtemp, 0, j);
|
||||
|
||||
boolean inQuote = true;
|
||||
|
|
|
@ -826,6 +826,10 @@ public final class SSLSocketImpl
|
|||
// reading lock
|
||||
private final ReentrantLock readLock = new ReentrantLock();
|
||||
|
||||
// closing status
|
||||
private volatile boolean isClosing;
|
||||
private volatile boolean hasDepleted;
|
||||
|
||||
AppInputStream() {
|
||||
this.appDataIsAvailable = false;
|
||||
this.buffer = ByteBuffer.allocate(4096);
|
||||
|
@ -871,8 +875,7 @@ public final class SSLSocketImpl
|
|||
* and returning "-1" on non-fault EOF status.
|
||||
*/
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException("the target buffer is null");
|
||||
} else if (off < 0 || len < 0 || len > b.length - off) {
|
||||
|
@ -900,12 +903,40 @@ public final class SSLSocketImpl
|
|||
throw new SocketException("Connection or inbound has closed");
|
||||
}
|
||||
|
||||
// Check if the input stream has been depleted.
|
||||
//
|
||||
// Note that the "hasDepleted" rather than the isClosing
|
||||
// filed is checked here, in case the closing process is
|
||||
// still in progress.
|
||||
if (hasDepleted) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.fine("The input stream has been depleted");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read the available bytes at first.
|
||||
//
|
||||
// Note that the receiving and processing of post-handshake message
|
||||
// are also synchronized with the read lock.
|
||||
readLock.lock();
|
||||
try {
|
||||
// Double check if the Socket is invalid (error or closed).
|
||||
if (conContext.isBroken || conContext.isInboundClosed()) {
|
||||
throw new SocketException(
|
||||
"Connection or inbound has closed");
|
||||
}
|
||||
|
||||
// Double check if the input stream has been depleted.
|
||||
if (hasDepleted) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.fine("The input stream is closing");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int remains = available();
|
||||
if (remains > 0) {
|
||||
int howmany = Math.min(remains, len);
|
||||
|
@ -938,7 +969,17 @@ public final class SSLSocketImpl
|
|||
return -1;
|
||||
}
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
// Check if the input stream is closing.
|
||||
//
|
||||
// If the deplete() did not hold the lock, clean up the
|
||||
// input stream here.
|
||||
try {
|
||||
if (isClosing) {
|
||||
readLockedDeplete();
|
||||
}
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,34 +1057,48 @@ public final class SSLSocketImpl
|
|||
* socket gracefully, without impact the performance too much.
|
||||
*/
|
||||
private void deplete() {
|
||||
if (conContext.isInboundClosed()) {
|
||||
if (conContext.isInboundClosed() || isClosing) {
|
||||
return;
|
||||
}
|
||||
|
||||
readLock.lock();
|
||||
try {
|
||||
// double check
|
||||
if (conContext.isInboundClosed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSLSocketInputRecord socketInputRecord =
|
||||
(SSLSocketInputRecord)conContext.inputRecord;
|
||||
isClosing = true;
|
||||
if (readLock.tryLock()) {
|
||||
try {
|
||||
socketInputRecord.deplete(
|
||||
conContext.isNegotiated && (getSoTimeout() > 0));
|
||||
} catch (IOException ioe) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.warning(
|
||||
"input stream close depletion failed", ioe);
|
||||
}
|
||||
readLockedDeplete();
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to use up the input records.
|
||||
*
|
||||
* Please don't call this method unless the readLock is held by
|
||||
* the current thread.
|
||||
*/
|
||||
private void readLockedDeplete() {
|
||||
// double check
|
||||
if (hasDepleted || conContext.isInboundClosed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSLSocketInputRecord socketInputRecord =
|
||||
(SSLSocketInputRecord)conContext.inputRecord;
|
||||
try {
|
||||
socketInputRecord.deplete(
|
||||
conContext.isNegotiated && (getSoTimeout() > 0));
|
||||
} catch (Exception ex) {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.warning(
|
||||
"input stream close depletion failed", ex);
|
||||
}
|
||||
} finally {
|
||||
readLock.unlock();
|
||||
hasDepleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue