mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
Merge
This commit is contained in:
commit
deba30de16
2767 changed files with 221508 additions and 36593 deletions
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.AlgorithmParametersSpi;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the parameter set used with the ChaCha20-Poly1305
|
||||
* algorithm. The parameter definition comes from
|
||||
* <a href="https://tools.ietf.org/html/rfc8103"><i>RFC 8103</i></a>
|
||||
* and is defined according to the following ASN.1:
|
||||
*
|
||||
* <pre>
|
||||
* id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
|
||||
pkcs9(9) smime(16) alg(3) 18 }
|
||||
|
||||
* AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12))
|
||||
* </pre>
|
||||
*
|
||||
* The AlgorithmParameters may be instantiated either by its name
|
||||
* ("ChaCha20-Poly1305") or via its OID (1.2.840.113549.1.9.16.3.18)
|
||||
*/
|
||||
public final class ChaCha20Poly1305Parameters extends AlgorithmParametersSpi {
|
||||
|
||||
private static final String DEFAULT_FMT = "ASN.1";
|
||||
private byte[] nonce;
|
||||
|
||||
public ChaCha20Poly1305Parameters() {}
|
||||
|
||||
/**
|
||||
* Initialize the ChaCha20Poly1305Parameters using an IvParameterSpec.
|
||||
*
|
||||
* @param paramSpec the {@code IvParameterSpec} used to configure
|
||||
* this object.
|
||||
*
|
||||
* @throws InvalidParameterSpecException if an object of a type other
|
||||
* than {@code IvParameterSpec} is used.
|
||||
*/
|
||||
@Override
|
||||
protected void engineInit(AlgorithmParameterSpec paramSpec)
|
||||
throws InvalidParameterSpecException {
|
||||
|
||||
if (!(paramSpec instanceof IvParameterSpec)) {
|
||||
throw new InvalidParameterSpecException
|
||||
("Inappropriate parameter specification");
|
||||
}
|
||||
IvParameterSpec ivps = (IvParameterSpec)paramSpec;
|
||||
|
||||
// Obtain the nonce
|
||||
nonce = ivps.getIV();
|
||||
if (nonce.length != 12) {
|
||||
throw new InvalidParameterSpecException("ChaCha20-Poly1305 nonce" +
|
||||
" must be 12 bytes in length");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the ChaCha20Poly1305Parameters from a DER encoded
|
||||
* parameter block.
|
||||
|
||||
* @param encoded the DER encoding of the nonce as an OCTET STRING.
|
||||
*
|
||||
* @throws IOException if the encoded nonce is not 12 bytes long or a DER
|
||||
* decoding error occurs.
|
||||
*/
|
||||
@Override
|
||||
protected void engineInit(byte[] encoded) throws IOException {
|
||||
DerValue val = new DerValue(encoded);
|
||||
|
||||
// Get the nonce value
|
||||
nonce = val.getOctetString();
|
||||
if (nonce.length != 12) {
|
||||
throw new IOException(
|
||||
"ChaCha20-Poly1305 nonce must be 12 bytes in length");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the ChaCha20Poly1305Parameters from a DER encoded
|
||||
* parameter block.
|
||||
*
|
||||
* @param encoded the DER encoding of the nonce and initial block counter.
|
||||
* @param decodingMethod the decoding method. The only currently accepted
|
||||
* value is "ASN.1"
|
||||
*
|
||||
* @throws IOException if the encoded nonce is not 12 bytes long, a DER
|
||||
* decoding error occurs, or an unsupported decoding method is
|
||||
* provided.
|
||||
*/
|
||||
@Override
|
||||
protected void engineInit(byte[] encoded, String decodingMethod)
|
||||
throws IOException {
|
||||
if (decodingMethod == null ||
|
||||
decodingMethod.equalsIgnoreCase(DEFAULT_FMT)) {
|
||||
engineInit(encoded);
|
||||
} else {
|
||||
throw new IOException("Unsupported parameter format: " +
|
||||
decodingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an IvParameterSpec with the same parameters as those
|
||||
* held in this object.
|
||||
*
|
||||
* @param paramSpec the class name of the spec. In this case it should
|
||||
* be {@code IvParameterSpec.class}.
|
||||
*
|
||||
* @return a {@code IvParameterSpec} object containing the nonce
|
||||
* value held in this object.
|
||||
*
|
||||
* @throws InvalidParameterSpecException if a class other than
|
||||
* {@code IvParameterSpec.class} was specified in the paramSpec
|
||||
* parameter.
|
||||
*/
|
||||
@Override
|
||||
protected <T extends AlgorithmParameterSpec>
|
||||
T engineGetParameterSpec(Class<T> paramSpec)
|
||||
throws InvalidParameterSpecException {
|
||||
|
||||
if (IvParameterSpec.class.isAssignableFrom(paramSpec)) {
|
||||
return paramSpec.cast(new IvParameterSpec(nonce));
|
||||
} else {
|
||||
throw new InvalidParameterSpecException
|
||||
("Inappropriate parameter specification");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the encoded parameters in ASN.1 form.
|
||||
*
|
||||
* @return a byte array containing the DER-encoding for the
|
||||
* ChaCha20-Poly1305 parameters. This will be the nonce
|
||||
* encoded as a DER OCTET STRING.
|
||||
*
|
||||
* @throws IOException if any DER encoding error occurs.
|
||||
*/
|
||||
@Override
|
||||
protected byte[] engineGetEncoded() throws IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.write(DerValue.tag_OctetString, nonce);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the encoded parameters in ASN.1 form.
|
||||
*
|
||||
* @param encodingMethod the encoding method to be used. This parameter
|
||||
* must be "ASN.1" as it is the only currently supported encoding
|
||||
* format. If the parameter is {@code null} then the default
|
||||
* encoding format will be used.
|
||||
*
|
||||
* @return a byte array containing the DER-encoding for the
|
||||
* ChaCha20-Poly1305 parameters.
|
||||
*
|
||||
* @throws IOException if any DER encoding error occurs or an unsupported
|
||||
* encoding method is provided.
|
||||
*/
|
||||
@Override
|
||||
protected byte[] engineGetEncoded(String encodingMethod)
|
||||
throws IOException {
|
||||
if (encodingMethod == null ||
|
||||
encodingMethod.equalsIgnoreCase(DEFAULT_FMT)) {
|
||||
return engineGetEncoded();
|
||||
} else {
|
||||
throw new IOException("Unsupported encoding format: " +
|
||||
encodingMethod);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatted string describing the parameters.
|
||||
*
|
||||
* @return a string representation of the ChaCha20 parameters.
|
||||
*/
|
||||
@Override
|
||||
protected String engineToString() {
|
||||
String LINE_SEP = System.lineSeparator();
|
||||
HexDumpEncoder encoder = new HexDumpEncoder();
|
||||
StringBuilder sb = new StringBuilder(LINE_SEP + "nonce:" +
|
||||
LINE_SEP + "[" + encoder.encodeBuffer(nonce) + "]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
|
@ -111,16 +111,20 @@ final class KeyGeneratorCore {
|
|||
protected HmacSHA2KG(String algoName, int len) {
|
||||
core = new KeyGeneratorCore(algoName, len);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(SecureRandom random) {
|
||||
core.implInit(random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException {
|
||||
core.implInit(params, random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(int keySize, SecureRandom random) {
|
||||
core.implInit(keySize, random);
|
||||
}
|
||||
@Override
|
||||
protected SecretKey engineGenerateKey() {
|
||||
return core.implGenerateKey();
|
||||
}
|
||||
|
@ -153,13 +157,16 @@ final class KeyGeneratorCore {
|
|||
public RC2KeyGenerator() {
|
||||
core = new KeyGeneratorCore("RC2", 128);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(SecureRandom random) {
|
||||
core.implInit(random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException {
|
||||
core.implInit(params, random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(int keySize, SecureRandom random) {
|
||||
if ((keySize < 40) || (keySize > 1024)) {
|
||||
throw new InvalidParameterException("Key length for RC2"
|
||||
|
@ -167,6 +174,7 @@ final class KeyGeneratorCore {
|
|||
}
|
||||
core.implInit(keySize, random);
|
||||
}
|
||||
@Override
|
||||
protected SecretKey engineGenerateKey() {
|
||||
return core.implGenerateKey();
|
||||
}
|
||||
|
@ -178,13 +186,16 @@ final class KeyGeneratorCore {
|
|||
public ARCFOURKeyGenerator() {
|
||||
core = new KeyGeneratorCore("ARCFOUR", 128);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(SecureRandom random) {
|
||||
core.implInit(random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException {
|
||||
core.implInit(params, random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(int keySize, SecureRandom random) {
|
||||
if ((keySize < 40) || (keySize > 1024)) {
|
||||
throw new InvalidParameterException("Key length for ARCFOUR"
|
||||
|
@ -192,9 +203,38 @@ final class KeyGeneratorCore {
|
|||
}
|
||||
core.implInit(keySize, random);
|
||||
}
|
||||
@Override
|
||||
protected SecretKey engineGenerateKey() {
|
||||
return core.implGenerateKey();
|
||||
}
|
||||
}
|
||||
|
||||
// nested static class for the ChaCha20 key generator
|
||||
public static final class ChaCha20KeyGenerator extends KeyGeneratorSpi {
|
||||
private final KeyGeneratorCore core;
|
||||
public ChaCha20KeyGenerator() {
|
||||
core = new KeyGeneratorCore("ChaCha20", 256);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(SecureRandom random) {
|
||||
core.implInit(random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException {
|
||||
core.implInit(params, random);
|
||||
}
|
||||
@Override
|
||||
protected void engineInit(int keySize, SecureRandom random) {
|
||||
if (keySize != 256) {
|
||||
throw new InvalidParameterException(
|
||||
"Key length for ChaCha20 must be 256 bits");
|
||||
}
|
||||
core.implInit(keySize, random);
|
||||
}
|
||||
@Override
|
||||
protected SecretKey engineGenerateKey() {
|
||||
return core.implGenerateKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.crypto.provider;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.Key;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.security.util.math.*;
|
||||
import sun.security.util.math.intpoly.*;
|
||||
|
||||
/**
|
||||
* This class represents the Poly1305 function defined in RFC 7539.
|
||||
*
|
||||
* This function is used in the implementation of ChaCha20/Poly1305
|
||||
* AEAD mode.
|
||||
*/
|
||||
final class Poly1305 {
|
||||
|
||||
private static final int KEY_LENGTH = 32;
|
||||
private static final int RS_LENGTH = KEY_LENGTH / 2;
|
||||
private static final int BLOCK_LENGTH = 16;
|
||||
private static final int TAG_LENGTH = 16;
|
||||
|
||||
private static final IntegerFieldModuloP ipl1305 =
|
||||
new IntegerPolynomial1305();
|
||||
|
||||
private byte[] keyBytes;
|
||||
private final byte[] block = new byte[BLOCK_LENGTH];
|
||||
private int blockOffset;
|
||||
|
||||
private IntegerModuloP r;
|
||||
private IntegerModuloP s;
|
||||
private MutableIntegerModuloP a;
|
||||
private final MutableIntegerModuloP n = ipl1305.get1().mutable();
|
||||
|
||||
Poly1305() { }
|
||||
|
||||
/**
|
||||
* Initialize the Poly1305 object
|
||||
*
|
||||
* @param newKey the {@code Key} which will be used for the authentication.
|
||||
* @param params this parameter is unused.
|
||||
*
|
||||
* @throws InvalidKeyException if {@code newKey} is {@code null} or is
|
||||
* not 32 bytes in length.
|
||||
*/
|
||||
void engineInit(Key newKey, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException {
|
||||
Objects.requireNonNull(newKey, "Null key provided during init");
|
||||
keyBytes = newKey.getEncoded();
|
||||
if (keyBytes == null) {
|
||||
throw new InvalidKeyException("Key does not support encoding");
|
||||
} else if (keyBytes.length != KEY_LENGTH) {
|
||||
throw new InvalidKeyException("Incorrect length for key: " +
|
||||
keyBytes.length);
|
||||
}
|
||||
|
||||
engineReset();
|
||||
setRSVals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the MAC (authentication tag).
|
||||
*
|
||||
* @return the length of the auth tag, which is always 16 bytes.
|
||||
*/
|
||||
int engineGetMacLength() {
|
||||
return TAG_LENGTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the Poly1305 object, discarding any current operation but
|
||||
* maintaining the same key.
|
||||
*/
|
||||
void engineReset() {
|
||||
// Clear the block and reset the offset
|
||||
Arrays.fill(block, (byte)0);
|
||||
blockOffset = 0;
|
||||
// Discard any previous accumulator and start at zero
|
||||
a = ipl1305.get0().mutable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the MAC with bytes from a {@code ByteBuffer}
|
||||
*
|
||||
* @param buf the {@code ByteBuffer} containing the data to be consumed.
|
||||
* Upon return the buffer's position will be equal to its limit.
|
||||
*/
|
||||
void engineUpdate(ByteBuffer buf) {
|
||||
int remaining = buf.remaining();
|
||||
while (remaining > 0) {
|
||||
int bytesToWrite = Integer.min(remaining,
|
||||
BLOCK_LENGTH - blockOffset);
|
||||
|
||||
if (bytesToWrite >= BLOCK_LENGTH) {
|
||||
// If bytes to write == BLOCK_LENGTH, then we have no
|
||||
// left-over data from previous updates and we can create
|
||||
// the IntegerModuloP directly from the input buffer.
|
||||
processBlock(buf, bytesToWrite);
|
||||
} else {
|
||||
// We have some left-over data from previous updates, so
|
||||
// copy that into the holding block until we get a full block.
|
||||
buf.get(block, blockOffset, bytesToWrite);
|
||||
blockOffset += bytesToWrite;
|
||||
|
||||
if (blockOffset >= BLOCK_LENGTH) {
|
||||
processBlock(block, 0, BLOCK_LENGTH);
|
||||
blockOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
remaining -= bytesToWrite;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the MAC with bytes from an array.
|
||||
*
|
||||
* @param input the input bytes.
|
||||
* @param offset the starting index from which to update the MAC.
|
||||
* @param len the number of bytes to process.
|
||||
*/
|
||||
void engineUpdate(byte[] input, int offset, int len) {
|
||||
Objects.checkFromIndexSize(offset, len, input.length);
|
||||
if (blockOffset > 0) {
|
||||
// We have some left-over data from previous updates
|
||||
int blockSpaceLeft = BLOCK_LENGTH - blockOffset;
|
||||
if (len < blockSpaceLeft) {
|
||||
System.arraycopy(input, offset, block, blockOffset, len);
|
||||
blockOffset += len;
|
||||
return; // block wasn't filled
|
||||
} else {
|
||||
System.arraycopy(input, offset, block, blockOffset,
|
||||
blockSpaceLeft);
|
||||
offset += blockSpaceLeft;
|
||||
len -= blockSpaceLeft;
|
||||
processBlock(block, 0, BLOCK_LENGTH);
|
||||
blockOffset = 0;
|
||||
}
|
||||
}
|
||||
while (len >= BLOCK_LENGTH) {
|
||||
processBlock(input, offset, BLOCK_LENGTH);
|
||||
offset += BLOCK_LENGTH;
|
||||
len -= BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) { // and len < BLOCK_LENGTH
|
||||
System.arraycopy(input, offset, block, 0, len);
|
||||
blockOffset = len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the MAC with a single byte of input
|
||||
*
|
||||
* @param input the byte to update the MAC with.
|
||||
*/
|
||||
void engineUpdate(byte input) {
|
||||
assert (blockOffset < BLOCK_LENGTH);
|
||||
// we can't hold fully filled unprocessed block
|
||||
block[blockOffset++] = input;
|
||||
|
||||
if (blockOffset == BLOCK_LENGTH) {
|
||||
processBlock(block, 0, BLOCK_LENGTH);
|
||||
blockOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finish the authentication operation and reset the MAC for a new
|
||||
* authentication operation.
|
||||
*
|
||||
* @return the authentication tag as a byte array.
|
||||
*/
|
||||
byte[] engineDoFinal() {
|
||||
byte[] tag = new byte[BLOCK_LENGTH];
|
||||
|
||||
// Finish up: process any remaining data < BLOCK_SIZE, then
|
||||
// create the tag from the resulting little-endian integer.
|
||||
if (blockOffset > 0) {
|
||||
processBlock(block, 0, blockOffset);
|
||||
blockOffset = 0;
|
||||
}
|
||||
|
||||
// Add in the s-half of the key to the accumulator
|
||||
a.addModPowerTwo(s, tag);
|
||||
|
||||
// Reset for the next auth
|
||||
engineReset();
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a single block of data. This should only be called
|
||||
* when the block array is complete. That may not necessarily
|
||||
* be a full 16 bytes if the last block has less than 16 bytes.
|
||||
*/
|
||||
private void processBlock(ByteBuffer buf, int len) {
|
||||
n.setValue(buf, len, (byte)0x01);
|
||||
a.setSum(n); // a += (n | 0x01)
|
||||
a.setProduct(r); // a = (a * r) % p
|
||||
}
|
||||
|
||||
private void processBlock(byte[] block, int offset, int length) {
|
||||
Objects.checkFromIndexSize(offset, length, block.length);
|
||||
n.setValue(block, offset, length, (byte)0x01);
|
||||
a.setSum(n); // a += (n | 0x01)
|
||||
a.setProduct(r); // a = (a * r) % p
|
||||
}
|
||||
|
||||
/**
|
||||
* Partition the authentication key into the R and S components, clamp
|
||||
* the R value, and instantiate IntegerModuloP objects to R and S's
|
||||
* numeric values.
|
||||
*/
|
||||
private void setRSVals() {
|
||||
// Clamp the bytes in the "r" half of the key.
|
||||
keyBytes[3] &= 15;
|
||||
keyBytes[7] &= 15;
|
||||
keyBytes[11] &= 15;
|
||||
keyBytes[15] &= 15;
|
||||
keyBytes[4] &= 252;
|
||||
keyBytes[8] &= 252;
|
||||
keyBytes[12] &= 252;
|
||||
|
||||
// Create IntegerModuloP elements from the r and s values
|
||||
r = ipl1305.getElement(keyBytes, 0, RS_LENGTH, (byte)0);
|
||||
s = ipl1305.getElement(keyBytes, RS_LENGTH, RS_LENGTH, (byte)0);
|
||||
}
|
||||
}
|
|
@ -57,6 +57,8 @@ import static sun.security.util.SecurityConstants.PROVIDER_VER;
|
|||
*
|
||||
* - ARCFOUR (RC4 compatible)
|
||||
*
|
||||
* - ChaCha20 (Stream cipher only and in AEAD mode with Poly1305)
|
||||
*
|
||||
* - Cipher modes ECB, CBC, CFB, OFB, PCBC, CTR, and CTS for all block ciphers
|
||||
* and mode GCM for AES cipher
|
||||
*
|
||||
|
@ -77,7 +79,7 @@ public final class SunJCE extends Provider {
|
|||
|
||||
private static final String info = "SunJCE Provider " +
|
||||
"(implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, "
|
||||
+ "Diffie-Hellman, HMAC)";
|
||||
+ "Diffie-Hellman, HMAC, ChaCha20)";
|
||||
|
||||
private static final String OID_PKCS12_RC4_128 = "1.2.840.113549.1.12.1.1";
|
||||
private static final String OID_PKCS12_RC4_40 = "1.2.840.113549.1.12.1.2";
|
||||
|
@ -336,6 +338,15 @@ public final class SunJCE extends Provider {
|
|||
put("Cipher.ARCFOUR SupportedPaddings", "NOPADDING");
|
||||
put("Cipher.ARCFOUR SupportedKeyFormats", "RAW");
|
||||
|
||||
put("Cipher.ChaCha20",
|
||||
"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Only");
|
||||
put("Cipher.ChaCha20 SupportedKeyFormats", "RAW");
|
||||
put("Cipher.ChaCha20-Poly1305",
|
||||
"com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305");
|
||||
put("Cipher.ChaCha20-Poly1305 SupportedKeyFormats", "RAW");
|
||||
put("Alg.Alias.Cipher.1.2.840.113549.1.9.16.3.18", "ChaCha20-Poly1305");
|
||||
put("Alg.Alias.Cipher.OID.1.2.840.113549.1.9.16.3.18", "ChaCha20-Poly1305");
|
||||
|
||||
/*
|
||||
* Key(pair) Generator engines
|
||||
*/
|
||||
|
@ -361,6 +372,10 @@ public final class SunJCE extends Provider {
|
|||
"ARCFOURKeyGenerator");
|
||||
put("Alg.Alias.KeyGenerator.RC4", "ARCFOUR");
|
||||
|
||||
put("KeyGenerator.ChaCha20",
|
||||
"com.sun.crypto.provider.KeyGeneratorCore$" +
|
||||
"ChaCha20KeyGenerator");
|
||||
|
||||
put("KeyGenerator.HmacMD5",
|
||||
"com.sun.crypto.provider.HmacMD5KeyGenerator");
|
||||
|
||||
|
@ -541,6 +556,9 @@ public final class SunJCE extends Provider {
|
|||
put("AlgorithmParameters.OAEP",
|
||||
"com.sun.crypto.provider.OAEPParameters");
|
||||
|
||||
put("AlgorithmParameters.ChaCha20-Poly1305",
|
||||
"com.sun.crypto.provider.ChaCha20Poly1305Parameters");
|
||||
|
||||
/*
|
||||
* Key factories
|
||||
*/
|
||||
|
|
|
@ -1419,7 +1419,8 @@ class Character implements java.io.Serializable, Comparable<Character> {
|
|||
"YIRADICALS");
|
||||
|
||||
/**
|
||||
* Constant for the "Cyrillic Supplementary" Unicode character block.
|
||||
* Constant for the "Cyrillic Supplement" Unicode character block.
|
||||
* This block was previously known as the "Cyrillic Supplementary" block.
|
||||
* @since 1.5
|
||||
*/
|
||||
public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY =
|
||||
|
|
|
@ -333,12 +333,12 @@ public class Object {
|
|||
* by being <em>notified</em> or <em>interrupted</em>, or until a
|
||||
* certain amount of real time has elapsed.
|
||||
* <p>
|
||||
* In all respects, this method behaves as if {@code wait(timeout, 0)}
|
||||
* In all respects, this method behaves as if {@code wait(timeoutMillis, 0)}
|
||||
* had been called. See the specification of the {@link #wait(long, int)} method
|
||||
* for details.
|
||||
*
|
||||
* @param timeout the maximum time to wait, in milliseconds
|
||||
* @throws IllegalArgumentException if the value of {@code timeout} is negative
|
||||
* @param timeoutMillis the maximum time to wait, in milliseconds
|
||||
* @throws IllegalArgumentException if {@code timeoutMillis} is negative
|
||||
* @throws IllegalMonitorStateException if the current thread is not
|
||||
* the owner of the object's monitor
|
||||
* @throws InterruptedException if any thread interrupted the current thread before or
|
||||
|
@ -349,7 +349,7 @@ public class Object {
|
|||
* @see #wait()
|
||||
* @see #wait(long, int)
|
||||
*/
|
||||
public final native void wait(long timeout) throws InterruptedException;
|
||||
public final native void wait(long timeoutMillis) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Causes the current thread to wait until it is awakened, typically
|
||||
|
@ -378,7 +378,7 @@ public class Object {
|
|||
* thread <var>T</var>.
|
||||
* <li>The specified amount of real time has elapsed, more or less.
|
||||
* The amount of real time, in nanoseconds, is given by the expression
|
||||
* {@code 1000000 * timeout + nanos}. If {@code timeout} and {@code nanos}
|
||||
* {@code 1000000 * timeoutMillis + nanos}. If {@code timeoutMillis} and {@code nanos}
|
||||
* are both zero, then real time is not taken into consideration and the
|
||||
* thread waits until awakened by one of the other causes.
|
||||
* <li>Thread <var>T</var> is awakened spuriously. (See below.)
|
||||
|
@ -423,17 +423,17 @@ public class Object {
|
|||
* <pre>{@code
|
||||
* synchronized (obj) {
|
||||
* while (<condition does not hold> and <timeout not exceeded>) {
|
||||
* long timeout = ... ; // recompute timeout values
|
||||
* long timeoutMillis = ... ; // recompute timeout values
|
||||
* int nanos = ... ;
|
||||
* obj.wait(timeout, nanos);
|
||||
* obj.wait(timeoutMillis, nanos);
|
||||
* }
|
||||
* ... // Perform action appropriate to condition or timeout
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* @param timeout the maximum time to wait, in milliseconds
|
||||
* @param timeoutMillis the maximum time to wait, in milliseconds
|
||||
* @param nanos additional time, in nanoseconds, in the range range 0-999999 inclusive
|
||||
* @throws IllegalArgumentException if the value of {@code timeout} is negative,
|
||||
* @throws IllegalArgumentException if {@code timeoutMillis} is negative,
|
||||
* or if the value of {@code nanos} is out of range
|
||||
* @throws IllegalMonitorStateException if the current thread is not
|
||||
* the owner of the object's monitor
|
||||
|
@ -445,9 +445,9 @@ public class Object {
|
|||
* @see #wait()
|
||||
* @see #wait(long)
|
||||
*/
|
||||
public final void wait(long timeout, int nanos) throws InterruptedException {
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("timeout value is negative");
|
||||
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
|
||||
if (timeoutMillis < 0) {
|
||||
throw new IllegalArgumentException("timeoutMillis value is negative");
|
||||
}
|
||||
|
||||
if (nanos < 0 || nanos > 999999) {
|
||||
|
@ -456,10 +456,10 @@ public class Object {
|
|||
}
|
||||
|
||||
if (nanos > 0) {
|
||||
timeout++;
|
||||
timeoutMillis++;
|
||||
}
|
||||
|
||||
wait(timeout);
|
||||
wait(timeoutMillis);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -607,8 +607,9 @@ public final class System {
|
|||
* <tr><th scope="row">{@code java.home}</th>
|
||||
* <td>Java installation directory</td></tr>
|
||||
* <tr><th scope="row">{@code java.vm.specification.version}</th>
|
||||
* <td>Java Virtual Machine specification version which may be
|
||||
* interpreted as a {@link Runtime.Version}</td></tr>
|
||||
* <td>Java Virtual Machine specification version, whose value is the
|
||||
* {@linkplain Runtime.Version#feature feature} element of the
|
||||
* {@linkplain Runtime#version() runtime version}</td></tr>
|
||||
* <tr><th scope="row">{@code java.vm.specification.vendor}</th>
|
||||
* <td>Java Virtual Machine specification vendor</td></tr>
|
||||
* <tr><th scope="row">{@code java.vm.specification.name}</th>
|
||||
|
@ -621,8 +622,9 @@ public final class System {
|
|||
* <tr><th scope="row">{@code java.vm.name}</th>
|
||||
* <td>Java Virtual Machine implementation name</td></tr>
|
||||
* <tr><th scope="row">{@code java.specification.version}</th>
|
||||
* <td>Java Runtime Environment specification version which may be
|
||||
* interpreted as a {@link Runtime.Version}</td></tr>
|
||||
* <td>Java Runtime Environment specification version, whose value is
|
||||
* the {@linkplain Runtime.Version#feature feature} element of the
|
||||
* {@linkplain Runtime#version() runtime version}</td></tr>
|
||||
* <tr><th scope="row">{@code java.specification.vendor}</th>
|
||||
* <td>Java Runtime Environment specification vendor</td></tr>
|
||||
* <tr><th scope="row">{@code java.specification.name}</th>
|
||||
|
|
|
@ -937,26 +937,6 @@ class Thread implements Runnable {
|
|||
stop0(new ThreadDeath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws {@code UnsupportedOperationException}.
|
||||
*
|
||||
* @param obj ignored
|
||||
*
|
||||
* @deprecated This method was originally designed to force a thread to stop
|
||||
* and throw a given {@code Throwable} as an exception. It was
|
||||
* inherently unsafe (see {@link #stop()} for details), and furthermore
|
||||
* could be used to generate exceptions that the target thread was
|
||||
* not prepared to handle.
|
||||
* For more information, see
|
||||
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
|
||||
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
* This method is subject to removal in a future version of Java SE.
|
||||
*/
|
||||
@Deprecated(since="1.2", forRemoval=true)
|
||||
public final synchronized void stop(Throwable obj) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupts this thread.
|
||||
*
|
||||
|
@ -1061,29 +1041,6 @@ class Thread implements Runnable {
|
|||
@HotSpotIntrinsicCandidate
|
||||
private native boolean isInterrupted(boolean ClearInterrupted);
|
||||
|
||||
/**
|
||||
* Throws {@link NoSuchMethodError}.
|
||||
*
|
||||
* @deprecated This method was originally designed to destroy this
|
||||
* thread without any cleanup. Any monitors it held would have
|
||||
* remained locked. However, the method was never implemented.
|
||||
* If it were to be implemented, it would be deadlock-prone in
|
||||
* much the manner of {@link #suspend}. If the target thread held
|
||||
* a lock protecting a critical system resource when it was
|
||||
* destroyed, no thread could ever access this resource again.
|
||||
* If another thread ever attempted to lock this resource, deadlock
|
||||
* would result. Such deadlocks typically manifest themselves as
|
||||
* "frozen" processes. For more information, see
|
||||
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">
|
||||
* Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
|
||||
* This method is subject to removal in a future version of Java SE.
|
||||
* @throws NoSuchMethodError always
|
||||
*/
|
||||
@Deprecated(since="1.5", forRemoval=true)
|
||||
public void destroy() {
|
||||
throw new NoSuchMethodError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if this thread is alive. A thread is alive if it has
|
||||
* been started and has not yet died.
|
||||
|
|
|
@ -62,21 +62,6 @@ it succeeded. The code to ensure this would be quite complex.</li>
|
|||
</ol>
|
||||
In sum, it just isn't practical.
|
||||
<hr>
|
||||
<h3>What about <code>Thread.stop(Throwable)</code>?</h3>
|
||||
<p>In addition to all of the problems noted above, this method may
|
||||
be used to generate exceptions that its target thread is unprepared
|
||||
to handle (including checked exceptions that the thread could not
|
||||
possibly throw, were it not for this method). For example, the
|
||||
following method is behaviorally identical to Java's
|
||||
<code>throw</code> operation, but circumvents the compiler's
|
||||
attempts to guarantee that the calling method has declared all of
|
||||
the checked exceptions that it may throw:</p>
|
||||
<pre>
|
||||
static void sneakyThrow(Throwable t) {
|
||||
Thread.currentThread().stop(t);
|
||||
}
|
||||
</pre>
|
||||
<hr>
|
||||
<h3>What should I use instead of <code>Thread.stop</code>?</h3>
|
||||
<p>Most uses of <code>stop</code> should be replaced by code that
|
||||
simply modifies some variable to indicate that the target thread
|
||||
|
@ -339,13 +324,6 @@ If the <code>stop</code> method calls <code>Thread.interrupt</code>, as
|
|||
described above, it needn't call <code>notify</code> as well, but it
|
||||
still must be synchronized. This ensures that the target thread
|
||||
won't miss an interrupt due to a race condition.
|
||||
<hr>
|
||||
<h3>What about <code>Thread.destroy</code>?</h3>
|
||||
<code>Thread.destroy</code> was never implemented and has been
|
||||
deprecated. If it were implemented, it would be deadlock-prone in
|
||||
the manner of <code>Thread.suspend</code>. (In fact, it is roughly
|
||||
equivalent to <code>Thread.suspend</code> without the possibility
|
||||
of a subsequent <code>Thread.resume</code>.)
|
||||
<p><!-- Body text ends here --></p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -134,6 +134,8 @@ final class BootstrapMethodInvoker {
|
|||
String recipe = (String)argv[0];
|
||||
Object[] shiftedArgs = Arrays.copyOfRange(argv, 1, argv.length);
|
||||
result = (CallSite)bootstrapMethod.invokeExact(caller, name, (MethodType)type, recipe, shiftedArgs);
|
||||
} else if (isLambdaMetafactoryAltMetafactoryBSM(bsmType)) {
|
||||
result = (CallSite)bootstrapMethod.invokeExact(caller, name, (MethodType)type, argv);
|
||||
} else {
|
||||
switch (argv.length) {
|
||||
case 0:
|
||||
|
@ -286,6 +288,9 @@ final class BootstrapMethodInvoker {
|
|||
private static final MethodType LMF_INDY_MT = MethodType.methodType(CallSite.class,
|
||||
Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||
|
||||
private static final MethodType LMF_ALT_MT = MethodType.methodType(CallSite.class,
|
||||
Lookup.class, String.class, MethodType.class, Object[].class);
|
||||
|
||||
private static final MethodType LMF_CONDY_MT = MethodType.methodType(Object.class,
|
||||
Lookup.class, String.class, Class.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||
|
||||
|
@ -319,6 +324,15 @@ final class BootstrapMethodInvoker {
|
|||
return bsmType == LMF_INDY_MT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true iff the BSM method type exactly matches
|
||||
* {@see java.lang.invoke.LambdaMetafactory#altMetafactory(
|
||||
* MethodHandles.Lookup,String,MethodType,Object[])}
|
||||
*/
|
||||
private static boolean isLambdaMetafactoryAltMetafactoryBSM(MethodType bsmType) {
|
||||
return bsmType == LMF_ALT_MT;
|
||||
}
|
||||
|
||||
/** The JVM produces java.lang.Integer values to box
|
||||
* CONSTANT_Integer boxes but does not intern them.
|
||||
* Let's intern them. This is slightly wrong for
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
|
@ -499,7 +499,6 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
|
|||
super(type, target);
|
||||
this.target = target;
|
||||
this.arrayType = arrayType;
|
||||
this.asCollectorCache = target.asCollector(arrayType, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3483,6 +3483,11 @@ assert((int)twice.invokeExact(21) == 42);
|
|||
* @return a method handle which inserts an additional argument,
|
||||
* before calling the original method handle
|
||||
* @throws NullPointerException if the target or the {@code values} array is null
|
||||
* @throws IllegalArgumentException if (@code pos) is less than {@code 0} or greater than
|
||||
* {@code N - L} where {@code N} is the arity of the target method handle and {@code L}
|
||||
* is the length of the values array.
|
||||
* @throws ClassCastException if an argument does not match the corresponding bound parameter
|
||||
* type.
|
||||
* @see MethodHandle#bindTo
|
||||
*/
|
||||
public static
|
||||
|
|
|
@ -43,17 +43,17 @@ public class ReferenceQueue<T> {
|
|||
*/
|
||||
public ReferenceQueue() { }
|
||||
|
||||
private static class Null<S> extends ReferenceQueue<S> {
|
||||
boolean enqueue(Reference<? extends S> r) {
|
||||
private static class Null extends ReferenceQueue<Object> {
|
||||
boolean enqueue(Reference<?> r) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ReferenceQueue<Object> NULL = new Null<>();
|
||||
static ReferenceQueue<Object> ENQUEUED = new Null<>();
|
||||
static final ReferenceQueue<Object> NULL = new Null();
|
||||
static final ReferenceQueue<Object> ENQUEUED = new Null();
|
||||
|
||||
private static class Lock { };
|
||||
private Lock lock = new Lock();
|
||||
private final Lock lock = new Lock();
|
||||
private volatile Reference<? extends T> head;
|
||||
private long queueLength = 0;
|
||||
|
||||
|
|
|
@ -109,10 +109,6 @@ class SocketOutputStream extends FileOutputStream {
|
|||
try {
|
||||
socketWrite0(fd, b, off, len);
|
||||
} catch (SocketException se) {
|
||||
if (se instanceof sun.net.ConnectionResetException) {
|
||||
impl.setConnectionReset();
|
||||
se = new SocketException("Connection reset");
|
||||
}
|
||||
if (impl.isClosedOrPending()) {
|
||||
throw new SocketException("Socket closed");
|
||||
} else {
|
||||
|
|
|
@ -189,6 +189,83 @@ public abstract class SelectionKey {
|
|||
*/
|
||||
public abstract SelectionKey interestOps(int ops);
|
||||
|
||||
/**
|
||||
* Atomically sets this key's interest set to the bitwise union ("or") of
|
||||
* the existing interest set and the given value. This method is guaranteed
|
||||
* to be atomic with respect to other concurrent calls to this method or to
|
||||
* {@link #interestOpsAnd(int)}.
|
||||
*
|
||||
* <p> This method may be invoked at any time. If this method is invoked
|
||||
* while a selection operation is in progress then it has no effect upon
|
||||
* that operation; the change to the key's interest set will be seen by the
|
||||
* next selection operation.
|
||||
*
|
||||
* @implSpec The default implementation synchronizes on this key and invokes
|
||||
* {@code interestOps()} and {@code interestOps(int)} to retrieve and set
|
||||
* this key's interest set.
|
||||
*
|
||||
* @param ops The interest set to apply
|
||||
*
|
||||
* @return The previous interest set
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If a bit in the set does not correspond to an operation that
|
||||
* is supported by this key's channel, that is, if
|
||||
* {@code (ops & ~channel().validOps()) != 0}
|
||||
*
|
||||
* @throws CancelledKeyException
|
||||
* If this key has been cancelled
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
public int interestOpsOr(int ops) {
|
||||
synchronized (this) {
|
||||
int oldVal = interestOps();
|
||||
interestOps(oldVal | ops);
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically sets this key's interest set to the bitwise intersection ("and")
|
||||
* of the existing interest set and the given value. This method is guaranteed
|
||||
* to be atomic with respect to other concurrent calls to this method or to
|
||||
* {@link #interestOpsOr(int)}.
|
||||
*
|
||||
* <p> This method may be invoked at any time. If this method is invoked
|
||||
* while a selection operation is in progress then it has no effect upon
|
||||
* that operation; the change to the key's interest set will be seen by the
|
||||
* next selection operation.
|
||||
*
|
||||
* @apiNote Unlike the {@code interestOps(int)} and {@code interestOpsOr(int)}
|
||||
* methods, this method does not throw {@code IllegalArgumentException} when
|
||||
* invoked with bits in the interest set that do not correspond to an
|
||||
* operation that is supported by this key's channel. This is to allow
|
||||
* operation bits in the interest set to be cleared using bitwise complement
|
||||
* values, e.g., {@code interestOpsAnd(~SelectionKey.OP_READ)} will remove
|
||||
* the {@code OP_READ} from the interest set without affecting other bits.
|
||||
*
|
||||
* @implSpec The default implementation synchronizes on this key and invokes
|
||||
* {@code interestOps()} and {@code interestOps(int)} to retrieve and set
|
||||
* this key's interest set.
|
||||
*
|
||||
* @param ops The interest set to apply
|
||||
*
|
||||
* @return The previous interest set
|
||||
*
|
||||
* @throws CancelledKeyException
|
||||
* If this key has been cancelled
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
public int interestOpsAnd(int ops) {
|
||||
synchronized (this) {
|
||||
int oldVal = interestOps();
|
||||
interestOps(oldVal & ops);
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves this key's ready-operation set.
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 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
|
||||
|
@ -1391,8 +1391,9 @@ public final class Files {
|
|||
* specific exception)</i>
|
||||
* @throws DirectoryNotEmptyException
|
||||
* the {@code REPLACE_EXISTING} option is specified but the file
|
||||
* cannot be replaced because it is a non-empty directory
|
||||
* <i>(optional specific exception)</i>
|
||||
* cannot be replaced because it is a non-empty directory, or the
|
||||
* source is a non-empty directory containing entries that would
|
||||
* be required to be moved <i>(optional specific exceptions)</i>
|
||||
* @throws AtomicMoveNotSupportedException
|
||||
* if the options array contains the {@code ATOMIC_MOVE} option but
|
||||
* the file cannot be moved as an atomic file system operation.
|
||||
|
|
|
@ -586,7 +586,7 @@ public abstract class Clock {
|
|||
* This is typically used for testing.
|
||||
*/
|
||||
static final class FixedClock extends Clock implements Serializable {
|
||||
private static final long serialVersionUID = 7430389292664866958L;
|
||||
private static final long serialVersionUID = 7430389292664866958L;
|
||||
private final Instant instant;
|
||||
private final ZoneId zone;
|
||||
|
||||
|
@ -636,7 +636,7 @@ public abstract class Clock {
|
|||
* Implementation of a clock that adds an offset to an underlying clock.
|
||||
*/
|
||||
static final class OffsetClock extends Clock implements Serializable {
|
||||
private static final long serialVersionUID = 2007484719125426256L;
|
||||
private static final long serialVersionUID = 2007484719125426256L;
|
||||
private final Clock baseClock;
|
||||
private final Duration offset;
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ public final class Duration
|
|||
* This method allows an arbitrary number of nanoseconds to be passed in.
|
||||
* The factory will alter the values of the second and nanosecond in order
|
||||
* to ensure that the stored nanosecond is in the range 0 to 999,999,999.
|
||||
* For example, the following will result in the exactly the same duration:
|
||||
* For example, the following will result in exactly the same duration:
|
||||
* <pre>
|
||||
* Duration.ofSeconds(3, 1);
|
||||
* Duration.ofSeconds(4, -999_999_999);
|
||||
|
@ -1357,12 +1357,14 @@ public final class Duration
|
|||
* Truncating the duration returns a copy of the original with conceptual fields
|
||||
* smaller than the specified unit set to zero.
|
||||
* For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
|
||||
* round down to the nearest minute, setting the seconds and nanoseconds to zero.
|
||||
* round down towards zero to the nearest minute, setting the seconds and
|
||||
* nanoseconds to zero.
|
||||
* <p>
|
||||
* The unit must have a {@linkplain TemporalUnit#getDuration() duration}
|
||||
* that divides into the length of a standard day without remainder.
|
||||
* This includes all supplied time units on {@link ChronoUnit} and
|
||||
* {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception.
|
||||
* This includes all
|
||||
* {@linkplain ChronoUnit#isTimeBased() time-based units on {@code ChronoUnit}}
|
||||
* and {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception.
|
||||
* <p>
|
||||
* This instance is immutable and unaffected by this method call.
|
||||
*
|
||||
|
@ -1388,7 +1390,7 @@ public final class Duration
|
|||
throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
|
||||
}
|
||||
long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
|
||||
long result = (nod / dur) * dur ;
|
||||
long result = (nod / dur) * dur;
|
||||
return plusNanos(result - nod);
|
||||
}
|
||||
|
||||
|
|
|
@ -311,7 +311,7 @@ public final class Instant
|
|||
* This method allows an arbitrary number of nanoseconds to be passed in.
|
||||
* The factory will alter the values of the second and nanosecond in order
|
||||
* to ensure that the stored nanosecond is in the range 0 to 999,999,999.
|
||||
* For example, the following will result in the exactly the same instant:
|
||||
* For example, the following will result in exactly the same instant:
|
||||
* <pre>
|
||||
* Instant.ofEpochSecond(3, 1);
|
||||
* Instant.ofEpochSecond(4, -999_999_999);
|
||||
|
@ -757,7 +757,7 @@ public final class Instant
|
|||
throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
|
||||
}
|
||||
long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
|
||||
long result = Math.floorDiv(nod, dur) * dur ;
|
||||
long result = Math.floorDiv(nod, dur) * dur;
|
||||
return plusNanos(result - nod);
|
||||
}
|
||||
|
||||
|
|
|
@ -356,14 +356,14 @@ public final class LocalTime
|
|||
* @return the local time, not null
|
||||
* @since 9
|
||||
*/
|
||||
public static LocalTime ofInstant(Instant instant, ZoneId zone) {
|
||||
Objects.requireNonNull(instant, "instant");
|
||||
Objects.requireNonNull(zone, "zone");
|
||||
ZoneOffset offset = zone.getRules().getOffset(instant);
|
||||
long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
|
||||
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
|
||||
}
|
||||
public static LocalTime ofInstant(Instant instant, ZoneId zone) {
|
||||
Objects.requireNonNull(instant, "instant");
|
||||
Objects.requireNonNull(zone, "zone");
|
||||
ZoneOffset offset = zone.getRules().getOffset(instant);
|
||||
long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
|
||||
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
|
|
|
@ -110,7 +110,7 @@ import java.util.Objects;
|
|||
* int year = date.get(ChronoField.YEAR);
|
||||
* System.out.printf(" Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
|
||||
* dow, day, month, year);
|
||||
|
||||
*
|
||||
* // Print today's date and the last day of the year
|
||||
* ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow();
|
||||
* ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1)
|
||||
|
|
|
@ -201,7 +201,7 @@ public interface ChronoLocalDateTime<D extends ChronoLocalDate>
|
|||
*
|
||||
* @return the date part of this date-time, not null
|
||||
*/
|
||||
D toLocalDate() ;
|
||||
D toLocalDate();
|
||||
|
||||
/**
|
||||
* Gets the local time part of this date-time.
|
||||
|
|
|
@ -736,8 +736,8 @@ public interface Chronology extends Comparable<Chronology> {
|
|||
* @throws DateTimeException if any of the values are out of range
|
||||
* @since 9
|
||||
*/
|
||||
public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
|
||||
int hour, int minute, int second, ZoneOffset zoneOffset) {
|
||||
public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
|
||||
int hour, int minute, int second, ZoneOffset zoneOffset) {
|
||||
Objects.requireNonNull(zoneOffset, "zoneOffset");
|
||||
HOUR_OF_DAY.checkValidValue(hour);
|
||||
MINUTE_OF_HOUR.checkValidValue(minute);
|
||||
|
@ -765,8 +765,8 @@ public interface Chronology extends Comparable<Chronology> {
|
|||
* @throws DateTimeException if any of the values are out of range
|
||||
* @since 9
|
||||
*/
|
||||
public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
|
||||
int hour, int minute, int second, ZoneOffset zoneOffset) {
|
||||
public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
|
||||
int hour, int minute, int second, ZoneOffset zoneOffset) {
|
||||
Objects.requireNonNull(era, "era");
|
||||
return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset);
|
||||
}
|
||||
|
|
|
@ -287,9 +287,9 @@ public final class IsoChronology extends AbstractChronology implements Serializa
|
|||
* or if the day-of-month is invalid for the month-of-year
|
||||
* @since 9
|
||||
*/
|
||||
@Override
|
||||
public long epochSecond(int prolepticYear, int month, int dayOfMonth,
|
||||
int hour, int minute, int second, ZoneOffset zoneOffset) {
|
||||
@Override
|
||||
public long epochSecond(int prolepticYear, int month, int dayOfMonth,
|
||||
int hour, int minute, int second, ZoneOffset zoneOffset) {
|
||||
YEAR.checkValidValue(prolepticYear);
|
||||
MONTH_OF_YEAR.checkValidValue(month);
|
||||
DAY_OF_MONTH.checkValidValue(dayOfMonth);
|
||||
|
|
|
@ -459,38 +459,38 @@ public final class JapaneseChronology extends AbstractChronology implements Seri
|
|||
return era.getPrivateEra().getSinceDate().getYear() + yearOfEra - 1;
|
||||
}
|
||||
|
||||
private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map<TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
|
||||
fieldValues.remove(ERA);
|
||||
fieldValues.remove(YEAR_OF_ERA);
|
||||
if (resolverStyle == ResolverStyle.LENIENT) {
|
||||
int y = prolepticYearLenient(era, yoe);
|
||||
long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
|
||||
long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
|
||||
return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS);
|
||||
}
|
||||
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR);
|
||||
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH);
|
||||
if (resolverStyle == ResolverStyle.SMART) { // previous valid
|
||||
if (yoe < 1) {
|
||||
throw new DateTimeException("Invalid YearOfEra: " + yoe);
|
||||
}
|
||||
int y = prolepticYearLenient(era, yoe);
|
||||
JapaneseDate result;
|
||||
try {
|
||||
result = date(y, moy, dom);
|
||||
} catch (DateTimeException ex) {
|
||||
result = date(y, moy, 1).with(TemporalAdjusters.lastDayOfMonth());
|
||||
}
|
||||
// handle the era being changed
|
||||
// only allow if the new date is in the same Jan-Dec as the era change
|
||||
// determine by ensuring either original yoe or result yoe is 1
|
||||
if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) {
|
||||
throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return date(era, yoe, moy, dom);
|
||||
}
|
||||
private ChronoLocalDate resolveYMD(JapaneseEra era, int yoe, Map<TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
|
||||
fieldValues.remove(ERA);
|
||||
fieldValues.remove(YEAR_OF_ERA);
|
||||
if (resolverStyle == ResolverStyle.LENIENT) {
|
||||
int y = prolepticYearLenient(era, yoe);
|
||||
long months = Math.subtractExact(fieldValues.remove(MONTH_OF_YEAR), 1);
|
||||
long days = Math.subtractExact(fieldValues.remove(DAY_OF_MONTH), 1);
|
||||
return date(y, 1, 1).plus(months, MONTHS).plus(days, DAYS);
|
||||
}
|
||||
int moy = range(MONTH_OF_YEAR).checkValidIntValue(fieldValues.remove(MONTH_OF_YEAR), MONTH_OF_YEAR);
|
||||
int dom = range(DAY_OF_MONTH).checkValidIntValue(fieldValues.remove(DAY_OF_MONTH), DAY_OF_MONTH);
|
||||
if (resolverStyle == ResolverStyle.SMART) { // previous valid
|
||||
if (yoe < 1) {
|
||||
throw new DateTimeException("Invalid YearOfEra: " + yoe);
|
||||
}
|
||||
int y = prolepticYearLenient(era, yoe);
|
||||
JapaneseDate result;
|
||||
try {
|
||||
result = date(y, moy, dom);
|
||||
} catch (DateTimeException ex) {
|
||||
result = date(y, moy, 1).with(TemporalAdjusters.lastDayOfMonth());
|
||||
}
|
||||
// handle the era being changed
|
||||
// only allow if the new date is in the same Jan-Dec as the era change
|
||||
// determine by ensuring either original yoe or result yoe is 1
|
||||
if (result.getEra() != era && result.get(YEAR_OF_ERA) > 1 && yoe > 1) {
|
||||
throw new DateTimeException("Invalid YearOfEra for Era: " + era + " " + yoe);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return date(era, yoe, moy, dom);
|
||||
}
|
||||
|
||||
private ChronoLocalDate resolveYD(JapaneseEra era, int yoe, Map <TemporalField,Long> fieldValues, ResolverStyle resolverStyle) {
|
||||
fieldValues.remove(ERA);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
|
@ -123,14 +123,19 @@ public final class JapaneseEra
|
|||
*/
|
||||
public static final JapaneseEra SHOWA = new JapaneseEra(1, LocalDate.of(1926, 12, 25));
|
||||
/**
|
||||
* The singleton instance for the 'Heisei' era (1989-01-08 - current)
|
||||
* The singleton instance for the 'Heisei' era (1989-01-08 - 2019-04-30)
|
||||
* which has the value 2.
|
||||
*/
|
||||
public static final JapaneseEra HEISEI = new JapaneseEra(2, LocalDate.of(1989, 1, 8));
|
||||
/**
|
||||
* The singleton instance for the 'NewEra' era (2019-05-01 - current)
|
||||
* which has the value 3.
|
||||
*/
|
||||
private static final JapaneseEra NEWERA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
|
||||
|
||||
// The number of predefined JapaneseEra constants.
|
||||
// There may be a supplemental era defined by the property.
|
||||
private static final int N_ERA_CONSTANTS = HEISEI.getValue() + ERA_OFFSET;
|
||||
private static final int N_ERA_CONSTANTS = NEWERA.getValue() + ERA_OFFSET;
|
||||
|
||||
/**
|
||||
* Serialization version.
|
||||
|
@ -148,6 +153,7 @@ public final class JapaneseEra
|
|||
KNOWN_ERAS[1] = TAISHO;
|
||||
KNOWN_ERAS[2] = SHOWA;
|
||||
KNOWN_ERAS[3] = HEISEI;
|
||||
KNOWN_ERAS[4] = NEWERA;
|
||||
for (int i = N_ERA_CONSTANTS; i < ERA_CONFIG.length; i++) {
|
||||
CalendarDate date = ERA_CONFIG[i].getSinceDate();
|
||||
LocalDate isoDate = LocalDate.of(date.getYear(), date.getMonth(), date.getDayOfMonth());
|
||||
|
|
|
@ -3049,7 +3049,7 @@ public final class DateTimeFormatterBuilder {
|
|||
* Prints and parses a numeric date-time field with optional padding.
|
||||
*/
|
||||
static final class FractionPrinterParser extends NumberPrinterParser {
|
||||
private final boolean decimalPoint;
|
||||
private final boolean decimalPoint;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
|
|
@ -216,7 +216,6 @@ public final class DecimalStyle {
|
|||
*
|
||||
* @param zeroDigit the character for zero
|
||||
* @return a copy with a new character that represents zero, not null
|
||||
|
||||
*/
|
||||
public DecimalStyle withZeroDigit(char zeroDigit) {
|
||||
if (zeroDigit == this.zeroDigit) {
|
||||
|
|
|
@ -119,7 +119,7 @@ import java.util.Collections;
|
|||
* Providers must ensure that once a rule has been seen by the application, the
|
||||
* rule must continue to be available.
|
||||
* <p>
|
||||
* Providers are encouraged to implement a meaningful {@code toString} method.
|
||||
* Providers are encouraged to implement a meaningful {@code toString} method.
|
||||
* <p>
|
||||
* Many systems would like to update time-zone rules dynamically without stopping the JVM.
|
||||
* When examined in detail, this is a complex problem.
|
||||
|
|
|
@ -2914,7 +2914,7 @@ public final class Formatter implements Closeable, Flushable {
|
|||
a.append(System.lineSeparator());
|
||||
break;
|
||||
case Conversion.PERCENT_SIGN:
|
||||
a.append('%');
|
||||
print("%", l);
|
||||
break;
|
||||
default:
|
||||
assert false;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
|
@ -50,6 +50,7 @@ import sun.util.calendar.ZoneInfo;
|
|||
* 2 Taisho 1912-07-30T00:00:00 local time
|
||||
* 3 Showa 1926-12-25T00:00:00 local time
|
||||
* 4 Heisei 1989-01-08T00:00:00 local time
|
||||
* 5 NewEra 2019-05-01T00:00:00 local time
|
||||
* ------------------------------------------------------
|
||||
* }</pre>
|
||||
*
|
||||
|
@ -71,8 +72,10 @@ import sun.util.calendar.ZoneInfo;
|
|||
* </pre>
|
||||
* where
|
||||
* <dl>
|
||||
* <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed)
|
||||
* <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed)
|
||||
* <dt>{@code <name>:}<dd>the full name of the new era (non-ASCII characters allowed,
|
||||
* either in platform's native encoding or in Unicode escape notation, {@code \\uXXXX})
|
||||
* <dt>{@code <abbr>:}<dd>the abbreviation of the new era (non-ASCII characters allowed,
|
||||
* either in platform's native encoding or in Unicode escape notation, {@code \\uXXXX})
|
||||
* <dt>{@code <time['u']>:}<dd>the start time of the new era represented by
|
||||
* milliseconds from 1970-01-01T00:00:00 local time or UTC if {@code 'u'} is
|
||||
* appended to the milliseconds value. (ASCII digits only)
|
||||
|
@ -125,6 +128,11 @@ class JapaneseImperialCalendar extends Calendar {
|
|||
*/
|
||||
public static final int HEISEI = 4;
|
||||
|
||||
/**
|
||||
* The ERA constant designating the NewEra era.
|
||||
*/
|
||||
private static final int NEWERA = 5;
|
||||
|
||||
private static final int EPOCH_OFFSET = 719163; // Fixed date of January 1, 1970 (Gregorian)
|
||||
|
||||
// Useful millisecond constants. Although ONE_DAY and ONE_WEEK can fit
|
||||
|
@ -155,6 +163,9 @@ class JapaneseImperialCalendar extends Calendar {
|
|||
// Fixed date of the first date of each era.
|
||||
private static final long[] sinceFixedDates;
|
||||
|
||||
// The current era
|
||||
private static final int currentEra;
|
||||
|
||||
/*
|
||||
* <pre>
|
||||
* Greatest Least
|
||||
|
@ -251,13 +262,18 @@ class JapaneseImperialCalendar extends Calendar {
|
|||
// eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
|
||||
// same as Gregorian.
|
||||
int index = BEFORE_MEIJI;
|
||||
int current = index;
|
||||
sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
|
||||
eras[index++] = BEFORE_MEIJI_ERA;
|
||||
for (Era e : es) {
|
||||
if(e.getSince(TimeZone.NO_TIMEZONE) < System.currentTimeMillis()) {
|
||||
current = index;
|
||||
}
|
||||
CalendarDate d = e.getSinceDate();
|
||||
sinceFixedDates[index] = gcal.getFixedDate(d);
|
||||
eras[index++] = e;
|
||||
}
|
||||
currentEra = current;
|
||||
|
||||
LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
|
||||
|
||||
|
@ -1743,12 +1759,12 @@ class JapaneseImperialCalendar extends Calendar {
|
|||
}
|
||||
} else if (transitionYear) {
|
||||
if (jdate.getYear() == 1) {
|
||||
// As of Heisei (since Meiji) there's no case
|
||||
// As of NewEra (since Meiji) there's no case
|
||||
// that there are multiple transitions in a
|
||||
// year. Historically there was such
|
||||
// case. There might be such case again in the
|
||||
// future.
|
||||
if (era > HEISEI) {
|
||||
if (era > NEWERA) {
|
||||
CalendarDate pd = eras[era - 1].getSinceDate();
|
||||
if (normalizedYear == pd.getYear()) {
|
||||
d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
|
||||
|
@ -1883,7 +1899,7 @@ class JapaneseImperialCalendar extends Calendar {
|
|||
year = isSet(YEAR) ? internalGet(YEAR) : 1;
|
||||
} else {
|
||||
if (isSet(YEAR)) {
|
||||
era = eras.length - 1;
|
||||
era = currentEra;
|
||||
year = internalGet(YEAR);
|
||||
} else {
|
||||
// Equivalent to 1970 (Gregorian)
|
||||
|
@ -2367,7 +2383,7 @@ class JapaneseImperialCalendar extends Calendar {
|
|||
* default ERA is the current era, but a zero (unset) ERA means before Meiji.
|
||||
*/
|
||||
private int internalGetEra() {
|
||||
return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
|
||||
return isSet(ERA) ? internalGet(ERA) : currentEra;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
package java.util.concurrent;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -191,6 +192,50 @@ public enum TimeUnit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given time duration to this unit.
|
||||
*
|
||||
* <p>For any TimeUnit {@code unit},
|
||||
* {@code unit.convert(Duration.ofNanos(n))}
|
||||
* is equivalent to
|
||||
* {@code unit.convert(n, NANOSECONDS)}, and
|
||||
* {@code unit.convert(Duration.of(n, unit.toChronoUnit()))}
|
||||
* is equivalent to {@code n} (in the absence of overflow).
|
||||
*
|
||||
* @param duration the time duration
|
||||
* @return the converted duration in this unit,
|
||||
* or {@code Long.MIN_VALUE} if conversion would negatively overflow,
|
||||
* or {@code Long.MAX_VALUE} if it would positively overflow.
|
||||
* @throws NullPointerException if {@code duration} is null
|
||||
* @see Duration#of(long,TemporalUnit)
|
||||
* @since 11
|
||||
*/
|
||||
public long convert(Duration duration) {
|
||||
long secs = duration.getSeconds();
|
||||
int nano = duration.getNano();
|
||||
if (secs < 0 && nano > 0) {
|
||||
// use representation compatible with integer division
|
||||
secs++;
|
||||
nano -= SECOND_SCALE;
|
||||
}
|
||||
final long s, nanoVal;
|
||||
// Optimize for the common case - NANOSECONDS without overflow
|
||||
if (this == NANOSECONDS)
|
||||
nanoVal = nano;
|
||||
else if ((s = scale) < SECOND_SCALE)
|
||||
nanoVal = nano / s;
|
||||
else if (this == SECONDS)
|
||||
return secs;
|
||||
else
|
||||
return secs / secRatio;
|
||||
long val = secs * secRatio + nanoVal;
|
||||
return ((secs < maxSecs && secs > -maxSecs) ||
|
||||
(secs == maxSecs && val > 0) ||
|
||||
(secs == -maxSecs && val < 0))
|
||||
? val
|
||||
: (secs > 0) ? Long.MAX_VALUE : Long.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to
|
||||
* {@link #convert(long, TimeUnit) NANOSECONDS.convert(duration, this)}.
|
||||
|
@ -221,10 +266,8 @@ public enum TimeUnit {
|
|||
*/
|
||||
public long toMicros(long duration) {
|
||||
long s, m;
|
||||
if ((s = scale) == MICRO_SCALE)
|
||||
return duration;
|
||||
else if (s < MICRO_SCALE)
|
||||
return duration / microRatio;
|
||||
if ((s = scale) <= MICRO_SCALE)
|
||||
return (s == MICRO_SCALE) ? duration : duration / microRatio;
|
||||
else if (duration > (m = maxMicros))
|
||||
return Long.MAX_VALUE;
|
||||
else if (duration < -m)
|
||||
|
@ -243,10 +286,8 @@ public enum TimeUnit {
|
|||
*/
|
||||
public long toMillis(long duration) {
|
||||
long s, m;
|
||||
if ((s = scale) == MILLI_SCALE)
|
||||
return duration;
|
||||
else if (s < MILLI_SCALE)
|
||||
return duration / milliRatio;
|
||||
if ((s = scale) <= MILLI_SCALE)
|
||||
return (s == MILLI_SCALE) ? duration : duration / milliRatio;
|
||||
else if (duration > (m = maxMillis))
|
||||
return Long.MAX_VALUE;
|
||||
else if (duration < -m)
|
||||
|
@ -265,10 +306,8 @@ public enum TimeUnit {
|
|||
*/
|
||||
public long toSeconds(long duration) {
|
||||
long s, m;
|
||||
if ((s = scale) == SECOND_SCALE)
|
||||
return duration;
|
||||
else if (s < SECOND_SCALE)
|
||||
return duration / secRatio;
|
||||
if ((s = scale) <= SECOND_SCALE)
|
||||
return (s == SECOND_SCALE) ? duration : duration / secRatio;
|
||||
else if (duration > (m = maxSecs))
|
||||
return Long.MAX_VALUE;
|
||||
else if (duration < -m)
|
||||
|
|
|
@ -116,4 +116,20 @@ public interface Predicate<T> {
|
|||
? Objects::isNull
|
||||
: object -> targetRef.equals(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a predicate that is the negation of the supplied predicate.
|
||||
*
|
||||
* @param <T> the type of arguments to the specified predicate
|
||||
* @param target predicate to negate
|
||||
*
|
||||
* @return a predicate that negates the results of the supplied
|
||||
* predicate
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T> Predicate<T> not(Predicate<? super T> target) {
|
||||
return (Predicate<T>)target.negate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -377,7 +377,8 @@ public class Attributes implements Map<Object,Object>, Cloneable {
|
|||
int len;
|
||||
while ((len = is.readLine(lbuf)) != -1) {
|
||||
boolean lineContinued = false;
|
||||
if (lbuf[--len] != '\n') {
|
||||
byte c = lbuf[--len];
|
||||
if (c != '\n' && c != '\r') {
|
||||
throw new IOException("line too long");
|
||||
}
|
||||
if (len > 0 && lbuf[len-1] == '\r') {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
|
@ -93,10 +93,14 @@ import java.util.zip.ZipFile;
|
|||
* argument. This assures that classes compatible with the major
|
||||
* version of the running JVM are loaded from multi-release jar files.
|
||||
*
|
||||
* <p>If the verify flag is on when opening a signed jar file, the content of
|
||||
* the file is verified against its signature embedded inside the file. Please
|
||||
* note that the verification process does not include validating the signer's
|
||||
* certificate. A caller should inspect the return value of
|
||||
* <p> If the {@code verify} flag is on when opening a signed jar file, the content
|
||||
* of the jar entry is verified against the signature embedded inside the manifest
|
||||
* that is associated with its {@link JarEntry#getRealName() path name}. For a
|
||||
* multi-release jar file, the content of a versioned entry is verfieid against
|
||||
* its own signature and {@link JarEntry#getCodeSigners()} returns its own signers.
|
||||
*
|
||||
* Please note that the verification process does not include validating the
|
||||
* signer's certificate. A caller should inspect the return value of
|
||||
* {@link JarEntry#getCodeSigners()} to further determine if the signature
|
||||
* can be trusted.
|
||||
*
|
||||
|
|
|
@ -205,7 +205,8 @@ public class Manifest implements Cloneable {
|
|||
byte[] lastline = null;
|
||||
|
||||
while ((len = fis.readLine(lbuf)) != -1) {
|
||||
if (lbuf[--len] != '\n') {
|
||||
byte c = lbuf[--len];
|
||||
if (c != '\n' && c != '\r') {
|
||||
throw new IOException("manifest line too long");
|
||||
}
|
||||
if (len > 0 && lbuf[len-1] == '\r') {
|
||||
|
@ -381,13 +382,38 @@ public class Manifest implements Cloneable {
|
|||
}
|
||||
int tpos = pos;
|
||||
int maxpos = tpos + n;
|
||||
while (tpos < maxpos && tbuf[tpos++] != '\n') ;
|
||||
byte c = 0;
|
||||
// jar.spec.newline: CRLF | LF | CR (not followed by LF)
|
||||
while (tpos < maxpos && (c = tbuf[tpos++]) != '\n' && c != '\r');
|
||||
if (c == '\r' && tpos < maxpos && tbuf[tpos] == '\n') {
|
||||
tpos++;
|
||||
}
|
||||
n = tpos - pos;
|
||||
System.arraycopy(tbuf, pos, b, off, n);
|
||||
off += n;
|
||||
total += n;
|
||||
pos = tpos;
|
||||
if (tbuf[tpos-1] == '\n') {
|
||||
c = tbuf[tpos-1];
|
||||
if (c == '\n') {
|
||||
break;
|
||||
}
|
||||
if (c == '\r') {
|
||||
if (count == pos) {
|
||||
// try to see if there is a trailing LF
|
||||
fill();
|
||||
if (pos < count && tbuf[pos] == '\n') {
|
||||
if (total < len) {
|
||||
b[off++] = '\n';
|
||||
total++;
|
||||
} else {
|
||||
// we should always have big enough lbuf but
|
||||
// just in case we don't, replace the last CR
|
||||
// with LF.
|
||||
b[off - 1] = '\n';
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
|
@ -37,8 +37,8 @@ import java.util.stream.Stream;
|
|||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* An engine that performs match operations on a {@linkplain java.lang.CharSequence
|
||||
* character sequence} by interpreting a {@link Pattern}.
|
||||
* An engine that performs match operations on a {@linkplain
|
||||
* java.lang.CharSequence character sequence} by interpreting a {@link Pattern}.
|
||||
*
|
||||
* <p> A matcher is created from a pattern by invoking the pattern's {@link
|
||||
* Pattern#matcher matcher} method. Once created, a matcher can be used to
|
||||
|
@ -52,8 +52,8 @@ import java.util.stream.StreamSupport;
|
|||
* <li><p> The {@link #lookingAt lookingAt} method attempts to match the
|
||||
* input sequence, starting at the beginning, against the pattern. </p></li>
|
||||
*
|
||||
* <li><p> The {@link #find find} method scans the input sequence looking for
|
||||
* the next subsequence that matches the pattern. </p></li>
|
||||
* <li><p> The {@link #find find} method scans the input sequence looking
|
||||
* for the next subsequence that matches the pattern. </p></li>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
|
@ -63,12 +63,12 @@ import java.util.stream.StreamSupport;
|
|||
*
|
||||
* <p> A matcher finds matches in a subset of its input called the
|
||||
* <i>region</i>. By default, the region contains all of the matcher's input.
|
||||
* The region can be modified via the {@link #region region} method and queried
|
||||
* via the {@link #regionStart regionStart} and {@link #regionEnd regionEnd}
|
||||
* methods. The way that the region boundaries interact with some pattern
|
||||
* constructs can be changed. See {@link #useAnchoringBounds
|
||||
* useAnchoringBounds} and {@link #useTransparentBounds useTransparentBounds}
|
||||
* for more details.
|
||||
* The region can be modified via the {@link #region(int, int) region} method
|
||||
* and queried via the {@link #regionStart() regionStart} and {@link
|
||||
* #regionEnd() regionEnd} methods. The way that the region boundaries interact
|
||||
* with some pattern constructs can be changed. See {@link
|
||||
* #useAnchoringBounds(boolean) useAnchoringBounds} and {@link
|
||||
* #useTransparentBounds(boolean) useTransparentBounds} for more details.
|
||||
*
|
||||
* <p> This class also defines methods for replacing matched subsequences with
|
||||
* new strings whose contents can, if desired, be computed from the match
|
||||
|
@ -586,8 +586,8 @@ public final class Matcher implements MatchResult {
|
|||
*
|
||||
* <p> For a matcher <i>m</i> with input sequence <i>s</i>,
|
||||
* the expressions <i>m.</i>{@code group()} and
|
||||
* <i>s.</i>{@code substring(}<i>m.</i>{@code start(),} <i>m.</i>{@code end())}
|
||||
* are equivalent. </p>
|
||||
* <i>s.</i>{@code substring(}<i>m.</i>{@code start(),} <i>m.</i>
|
||||
* {@code end())} are equivalent. </p>
|
||||
*
|
||||
* <p> Note that some patterns, for example {@code a*}, match the empty
|
||||
* string. This method will return the empty string when the pattern
|
||||
|
@ -652,8 +652,8 @@ public final class Matcher implements MatchResult {
|
|||
|
||||
/**
|
||||
* Returns the input subsequence captured by the given
|
||||
* <a href="Pattern.html#groupname">named-capturing group</a> during the previous
|
||||
* match operation.
|
||||
* <a href="Pattern.html#groupname">named-capturing group</a> during the
|
||||
* previous match operation.
|
||||
*
|
||||
* <p> If the match was successful but the group specified failed to match
|
||||
* any part of the input sequence, then {@code null} is returned. Note
|
||||
|
@ -866,9 +866,9 @@ public final class Matcher implements MatchResult {
|
|||
* string.
|
||||
*
|
||||
* <p> This method is intended to be used in a loop together with the
|
||||
* {@link #appendTail appendTail} and {@link #find find} methods. The
|
||||
* following code, for example, writes {@code one dog two dogs in the
|
||||
* yard} to the standard-output stream: </p>
|
||||
* {@link #appendTail(StringBuffer) appendTail} and {@link #find() find}
|
||||
* methods. The following code, for example, writes {@code one dog two dogs
|
||||
* in the yard} to the standard-output stream: </p>
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* Pattern p = Pattern.compile("cat");
|
||||
|
@ -959,9 +959,9 @@ public final class Matcher implements MatchResult {
|
|||
* string.
|
||||
*
|
||||
* <p> This method is intended to be used in a loop together with the
|
||||
* {@link #appendTail appendTail} and {@link #find find} methods. The
|
||||
* following code, for example, writes {@code one dog two dogs in the
|
||||
* yard} to the standard-output stream: </p>
|
||||
* {@link #appendTail(StringBuilder) appendTail} and
|
||||
* {@link #find() find} methods. The following code, for example, writes
|
||||
* {@code one dog two dogs in the yard} to the standard-output stream: </p>
|
||||
*
|
||||
* <blockquote><pre>
|
||||
* Pattern p = Pattern.compile("cat");
|
||||
|
@ -1104,8 +1104,8 @@ public final class Matcher implements MatchResult {
|
|||
* <p> This method reads characters from the input sequence, starting at
|
||||
* the append position, and appends them to the given string buffer. It is
|
||||
* intended to be invoked after one or more invocations of the {@link
|
||||
* #appendReplacement appendReplacement} method in order to copy the
|
||||
* remainder of the input sequence. </p>
|
||||
* #appendReplacement(StringBuffer, String) appendReplacement} method in
|
||||
* order to copy the remainder of the input sequence. </p>
|
||||
*
|
||||
* @param sb
|
||||
* The target string buffer
|
||||
|
@ -1123,8 +1123,9 @@ public final class Matcher implements MatchResult {
|
|||
* <p> This method reads characters from the input sequence, starting at
|
||||
* the append position, and appends them to the given string builder. It is
|
||||
* intended to be invoked after one or more invocations of the {@link
|
||||
* #appendReplacement appendReplacement} method in order to copy the
|
||||
* remainder of the input sequence. </p>
|
||||
* #appendReplacement(StringBuilder, String)
|
||||
* appendReplacement} method in order to copy the remainder of the input
|
||||
* sequence. </p>
|
||||
*
|
||||
* @param sb
|
||||
* The target string builder
|
||||
|
@ -1490,10 +1491,10 @@ public final class Matcher implements MatchResult {
|
|||
* index specified by the {@code end} parameter.
|
||||
*
|
||||
* <p>Depending on the transparency and anchoring being used (see
|
||||
* {@link #useTransparentBounds useTransparentBounds} and
|
||||
* {@link #useAnchoringBounds useAnchoringBounds}), certain constructs such
|
||||
* as anchors may behave differently at or around the boundaries of the
|
||||
* region.
|
||||
* {@link #useTransparentBounds(boolean) useTransparentBounds} and
|
||||
* {@link #useAnchoringBounds(boolean) useAnchoringBounds}), certain
|
||||
* constructs such as anchors may behave differently at or around the
|
||||
* boundaries of the region.
|
||||
*
|
||||
* @param start
|
||||
* The index to start searching at (inclusive)
|
||||
|
@ -1523,8 +1524,8 @@ public final class Matcher implements MatchResult {
|
|||
/**
|
||||
* Reports the start index of this matcher's region. The
|
||||
* searches this matcher conducts are limited to finding matches
|
||||
* within {@link #regionStart regionStart} (inclusive) and
|
||||
* {@link #regionEnd regionEnd} (exclusive).
|
||||
* within {@link #regionStart() regionStart} (inclusive) and
|
||||
* {@link #regionEnd() regionEnd} (exclusive).
|
||||
*
|
||||
* @return The starting point of this matcher's region
|
||||
* @since 1.5
|
||||
|
@ -1536,8 +1537,8 @@ public final class Matcher implements MatchResult {
|
|||
/**
|
||||
* Reports the end index (exclusive) of this matcher's region.
|
||||
* The searches this matcher conducts are limited to finding matches
|
||||
* within {@link #regionStart regionStart} (inclusive) and
|
||||
* {@link #regionEnd regionEnd} (exclusive).
|
||||
* within {@link #regionStart() regionStart} (inclusive) and
|
||||
* {@link #regionEnd() regionEnd} (exclusive).
|
||||
*
|
||||
* @return the ending point of this matcher's region
|
||||
* @since 1.5
|
||||
|
@ -1553,7 +1554,7 @@ public final class Matcher implements MatchResult {
|
|||
* <i>transparent</i> bounds, {@code false} if it uses <i>opaque</i>
|
||||
* bounds.
|
||||
*
|
||||
* <p> See {@link #useTransparentBounds useTransparentBounds} for a
|
||||
* <p> See {@link #useTransparentBounds(boolean) useTransparentBounds} for a
|
||||
* description of transparent and opaque bounds.
|
||||
*
|
||||
* <p> By default, a matcher uses opaque region boundaries.
|
||||
|
@ -1604,7 +1605,7 @@ public final class Matcher implements MatchResult {
|
|||
* <p> This method returns {@code true} if this matcher uses
|
||||
* <i>anchoring</i> bounds, {@code false} otherwise.
|
||||
*
|
||||
* <p> See {@link #useAnchoringBounds useAnchoringBounds} for a
|
||||
* <p> See {@link #useAnchoringBounds(boolean) useAnchoringBounds} for a
|
||||
* description of anchoring bounds.
|
||||
*
|
||||
* <p> By default, a matcher uses anchoring region boundaries.
|
||||
|
@ -1770,18 +1771,18 @@ public final class Matcher implements MatchResult {
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates a String from this Matcher's input in the specified range.
|
||||
* Generates a String from this matcher's input in the specified range.
|
||||
*
|
||||
* @param beginIndex the beginning index, inclusive
|
||||
* @param endIndex the ending index, exclusive
|
||||
* @return A String generated from this Matcher's input
|
||||
* @return A String generated from this matcher's input
|
||||
*/
|
||||
CharSequence getSubSequence(int beginIndex, int endIndex) {
|
||||
return text.subSequence(beginIndex, endIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this Matcher's input character at index i.
|
||||
* Returns this matcher's input character at index i.
|
||||
*
|
||||
* @return A char from the specified index
|
||||
*/
|
||||
|
@ -1802,4 +1803,4 @@ public final class Matcher implements MatchResult {
|
|||
throw new IllegalArgumentException("No group with name <" + name + ">");
|
||||
return parentPattern.namedGroups().get(name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ import sun.security.jca.*;
|
|||
* encryption with a given key. When IVs are repeated for GCM
|
||||
* encryption, such usages are subject to forgery attacks. Thus, after
|
||||
* each encryption operation using GCM mode, callers should re-initialize
|
||||
* the cipher objects with GCM parameters which has a different IV value.
|
||||
* the cipher objects with GCM parameters which have a different IV value.
|
||||
* <pre>
|
||||
* GCMParameterSpec s = ...;
|
||||
* cipher.init(..., s);
|
||||
|
@ -131,6 +131,13 @@ import sun.security.jca.*;
|
|||
* ...
|
||||
*
|
||||
* </pre>
|
||||
* The ChaCha20 and ChaCha20-Poly1305 algorithms have a similar requirement
|
||||
* for unique nonces with a given key. After each encryption or decryption
|
||||
* operation, callers should re-initialize their ChaCha20 or ChaCha20-Poly1305
|
||||
* ciphers with parameters that specify a different nonce value. Please
|
||||
* see <a href="https://tools.ietf.org/html/rfc7539">RFC 7539</a> for more
|
||||
* information on the ChaCha20 and ChaCha20-Poly1305 algorithms.
|
||||
* <p>
|
||||
* Every implementation of the Java platform is required to support
|
||||
* the following standard {@code Cipher} transformations with the keysizes
|
||||
* in parentheses:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
|
@ -755,6 +755,7 @@ public abstract class CipherSpi {
|
|||
return 0;
|
||||
}
|
||||
int outLenNeeded = engineGetOutputSize(inLen);
|
||||
|
||||
if (output.remaining() < outLenNeeded) {
|
||||
throw new ShortBufferException("Need at least " + outLenNeeded
|
||||
+ " bytes of space in output buffer");
|
||||
|
@ -762,98 +763,77 @@ public abstract class CipherSpi {
|
|||
|
||||
boolean a1 = input.hasArray();
|
||||
boolean a2 = output.hasArray();
|
||||
int total = 0;
|
||||
byte[] inArray, outArray;
|
||||
if (a2) { // output has an accessible byte[]
|
||||
outArray = output.array();
|
||||
int outPos = output.position();
|
||||
int outOfs = output.arrayOffset() + outPos;
|
||||
|
||||
if (a1 && a2) {
|
||||
byte[] inArray = input.array();
|
||||
int inOfs = input.arrayOffset() + inPos;
|
||||
byte[] outArray = output.array();
|
||||
int outPos = output.position();
|
||||
int outOfs = output.arrayOffset() + outPos;
|
||||
int n;
|
||||
if (isUpdate) {
|
||||
n = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
|
||||
} else {
|
||||
n = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
|
||||
}
|
||||
input.position(inLimit);
|
||||
output.position(outPos + n);
|
||||
return n;
|
||||
} else if (!a1 && a2) {
|
||||
int outPos = output.position();
|
||||
byte[] outArray = output.array();
|
||||
int outOfs = output.arrayOffset() + outPos;
|
||||
byte[] inArray = new byte[getTempArraySize(inLen)];
|
||||
int total = 0;
|
||||
do {
|
||||
int chunk = Math.min(inLen, inArray.length);
|
||||
if (chunk > 0) {
|
||||
input.get(inArray, 0, chunk);
|
||||
}
|
||||
int n;
|
||||
if (isUpdate || (inLen != chunk)) {
|
||||
n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
|
||||
} else {
|
||||
n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
|
||||
}
|
||||
total += n;
|
||||
outOfs += n;
|
||||
inLen -= chunk;
|
||||
} while (inLen > 0);
|
||||
output.position(outPos + total);
|
||||
return total;
|
||||
} else { // output is not backed by an accessible byte[]
|
||||
byte[] inArray;
|
||||
int inOfs;
|
||||
if (a1) {
|
||||
if (a1) { // input also has an accessible byte[]
|
||||
inArray = input.array();
|
||||
inOfs = input.arrayOffset() + inPos;
|
||||
} else {
|
||||
inArray = new byte[getTempArraySize(inLen)];
|
||||
inOfs = 0;
|
||||
}
|
||||
byte[] outArray = new byte[getTempArraySize(outLenNeeded)];
|
||||
int outSize = outArray.length;
|
||||
int total = 0;
|
||||
boolean resized = false;
|
||||
do {
|
||||
int chunk =
|
||||
Math.min(inLen, (outSize == 0? inArray.length : outSize));
|
||||
if (!a1 && !resized && chunk > 0) {
|
||||
input.get(inArray, 0, chunk);
|
||||
inOfs = 0;
|
||||
int inOfs = input.arrayOffset() + inPos;
|
||||
if (isUpdate) {
|
||||
total = engineUpdate(inArray, inOfs, inLen, outArray, outOfs);
|
||||
} else {
|
||||
total = engineDoFinal(inArray, inOfs, inLen, outArray, outOfs);
|
||||
}
|
||||
try {
|
||||
int n;
|
||||
if (isUpdate || (inLen != chunk)) {
|
||||
n = engineUpdate(inArray, inOfs, chunk, outArray, 0);
|
||||
} else {
|
||||
n = engineDoFinal(inArray, inOfs, chunk, outArray, 0);
|
||||
}
|
||||
resized = false;
|
||||
inOfs += chunk;
|
||||
inLen -= chunk;
|
||||
if (n > 0) {
|
||||
output.put(outArray, 0, n);
|
||||
total += n;
|
||||
}
|
||||
} catch (ShortBufferException e) {
|
||||
if (resized) {
|
||||
// we just resized the output buffer, but it still
|
||||
// did not work. Bug in the provider, abort
|
||||
throw (ProviderException)new ProviderException
|
||||
("Could not determine buffer size").initCause(e);
|
||||
}
|
||||
// output buffer is too small, realloc and try again
|
||||
resized = true;
|
||||
outSize = engineGetOutputSize(chunk);
|
||||
outArray = new byte[outSize];
|
||||
}
|
||||
} while (inLen > 0);
|
||||
if (a1) {
|
||||
input.position(inLimit);
|
||||
} else { // input does not have accessible byte[]
|
||||
inArray = new byte[getTempArraySize(inLen)];
|
||||
do {
|
||||
int chunk = Math.min(inLen, inArray.length);
|
||||
if (chunk > 0) {
|
||||
input.get(inArray, 0, chunk);
|
||||
}
|
||||
int n;
|
||||
if (isUpdate || (inLen > chunk)) {
|
||||
n = engineUpdate(inArray, 0, chunk, outArray, outOfs);
|
||||
} else {
|
||||
n = engineDoFinal(inArray, 0, chunk, outArray, outOfs);
|
||||
}
|
||||
total += n;
|
||||
outOfs += n;
|
||||
inLen -= chunk;
|
||||
} while (inLen > 0);
|
||||
}
|
||||
output.position(outPos + total);
|
||||
} else { // output does not have an accessible byte[]
|
||||
if (a1) { // but input has an accessible byte[]
|
||||
inArray = input.array();
|
||||
int inOfs = input.arrayOffset() + inPos;
|
||||
if (isUpdate) {
|
||||
outArray = engineUpdate(inArray, inOfs, inLen);
|
||||
} else {
|
||||
outArray = engineDoFinal(inArray, inOfs, inLen);
|
||||
}
|
||||
input.position(inLimit);
|
||||
if (outArray != null && outArray.length != 0) {
|
||||
output.put(outArray);
|
||||
total = outArray.length;
|
||||
}
|
||||
} else { // input also does not have an accessible byte[]
|
||||
inArray = new byte[getTempArraySize(inLen)];
|
||||
do {
|
||||
int chunk = Math.min(inLen, inArray.length);
|
||||
if (chunk > 0) {
|
||||
input.get(inArray, 0, chunk);
|
||||
}
|
||||
int n;
|
||||
if (isUpdate || (inLen > chunk)) {
|
||||
outArray = engineUpdate(inArray, 0, chunk);
|
||||
} else {
|
||||
outArray = engineDoFinal(inArray, 0, chunk);
|
||||
}
|
||||
if (outArray != null && outArray.length != 0) {
|
||||
output.put(outArray);
|
||||
total += outArray.length;
|
||||
}
|
||||
inLen -= chunk;
|
||||
} while (inLen > 0);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.crypto.spec;
|
||||
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class specifies the parameters used with the
|
||||
* <a href="https://tools.ietf.org/html/rfc7539"><i>ChaCha20</i></a>
|
||||
* algorithm.
|
||||
*
|
||||
* <p> The parameters consist of a 12-byte nonce and an initial
|
||||
* counter value expressed as a 32-bit integer.
|
||||
*
|
||||
* <p> This class can be used to initialize a {@code Cipher} object that
|
||||
* implements the <i>ChaCha20</i> algorithm.
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
public final class ChaCha20ParameterSpec implements AlgorithmParameterSpec {
|
||||
|
||||
// The nonce length is defined by the spec as 96 bits (12 bytes) in length.
|
||||
private static final int NONCE_LENGTH = 12;
|
||||
|
||||
private final byte[] nonce;
|
||||
private final int counter;
|
||||
|
||||
/**
|
||||
* Constructs a parameter set for ChaCha20 from the given nonce
|
||||
* and counter.
|
||||
*
|
||||
* @param nonce a 12-byte nonce value
|
||||
* @param counter the initial counter value
|
||||
*
|
||||
* @throws NullPointerException if {@code nonce} is {@code null}
|
||||
* @throws IllegalArgumentException if {@code nonce} is not 12 bytes
|
||||
* in length
|
||||
*/
|
||||
public ChaCha20ParameterSpec(byte[] nonce, int counter) {
|
||||
this.counter = counter;
|
||||
|
||||
Objects.requireNonNull(nonce, "Nonce must be non-null");
|
||||
this.nonce = nonce.clone();
|
||||
if (this.nonce.length != NONCE_LENGTH) {
|
||||
throw new IllegalArgumentException(
|
||||
"Nonce must be 12-bytes in length");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce value.
|
||||
*
|
||||
* @return the nonce value. This method returns a new array each time
|
||||
* this method is called.
|
||||
*/
|
||||
public byte[] getNonce() {
|
||||
return nonce.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured counter value.
|
||||
*
|
||||
* @return the counter value
|
||||
*/
|
||||
public int getCounter() {
|
||||
return counter;
|
||||
}
|
||||
}
|
|
@ -609,12 +609,13 @@ public final class LauncherHelper {
|
|||
}
|
||||
|
||||
// From src/share/bin/java.c:
|
||||
// enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR, LM_MODULE }
|
||||
// enum LaunchMode { LM_UNKNOWN = 0, LM_CLASS, LM_JAR, LM_MODULE, LM_SOURCE }
|
||||
|
||||
private static final int LM_UNKNOWN = 0;
|
||||
private static final int LM_CLASS = 1;
|
||||
private static final int LM_JAR = 2;
|
||||
private static final int LM_MODULE = 3;
|
||||
private static final int LM_SOURCE = 4;
|
||||
|
||||
static void abort(Throwable t, String msgKey, Object... args) {
|
||||
if (msgKey != null) {
|
||||
|
@ -645,13 +646,21 @@ public final class LauncherHelper {
|
|||
*
|
||||
* @return the application's main class
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static Class<?> checkAndLoadMain(boolean printToStderr,
|
||||
int mode,
|
||||
String what) {
|
||||
initOutput(printToStderr);
|
||||
|
||||
Class<?> mainClass = (mode == LM_MODULE) ? loadModuleMainClass(what)
|
||||
: loadMainClass(mode, what);
|
||||
Class<?> mainClass = null;
|
||||
switch (mode) {
|
||||
case LM_MODULE: case LM_SOURCE:
|
||||
mainClass = loadModuleMainClass(what);
|
||||
break;
|
||||
default:
|
||||
mainClass = loadMainClass(mode, what);
|
||||
break;
|
||||
}
|
||||
|
||||
// record the real main class for UI purposes
|
||||
// neither method above can return null, they will abort()
|
||||
|
|
|
@ -25,13 +25,17 @@
|
|||
|
||||
# Translators please note do not translate the options themselves
|
||||
java.launcher.opt.header = Usage: {0} [options] <mainclass> [args...]\n\
|
||||
\ (to execute a class)\n or {0} [options] -jar <jarfile> [args...]\n\
|
||||
\ (to execute a class)\n\
|
||||
\ or {0} [options] -jar <jarfile> [args...]\n\
|
||||
\ (to execute a jar file)\n\
|
||||
\ or {0} [options] -m <module>[/<mainclass>] [args...]\n\
|
||||
\ {0} [options] --module <module>[/<mainclass>] [args...]\n\
|
||||
\ (to execute the main class in a module)\n\n\
|
||||
\ Arguments following the main class, -jar <jarfile>, -m or --module\n\
|
||||
\ <module>/<mainclass> are passed as the arguments to main class.\n\n\
|
||||
\ (to execute the main class in a module)\n\
|
||||
\ or {0} [options] <sourcefile> [args]\n\
|
||||
\ (to execute a single source-file program)\n\n\
|
||||
\ Arguments following the main class, source file, -jar <jarfile>,\n\
|
||||
\ -m or --module <module>/<mainclass> are passed as the arguments to\n\
|
||||
\ main class.\n\n\
|
||||
\ where options include:\n\n
|
||||
|
||||
java.launcher.opt.vmselect =\ {0}\t to select the "{1}" VM\n
|
||||
|
@ -114,7 +118,7 @@ java.launcher.opt.footer = \
|
|||
\ -disable-@files\n\
|
||||
\ prevent further argument file expansion\n\
|
||||
\ --enable-preview\n\
|
||||
\ allow classes to depend on preview features of this release
|
||||
\ allow classes to depend on preview features of this release\n\
|
||||
\To specify an argument for a long option, you can use --<name>=<value> or\n\
|
||||
\--<name> <value>.\n
|
||||
|
||||
|
@ -180,7 +184,9 @@ java.launcher.X.usage=\n\
|
|||
\ --patch-module <module>=<file>({0}<file>)*\n\
|
||||
\ override or augment a module with classes and resources\n\
|
||||
\ in JAR files or directories.\n\
|
||||
\ --disable-@files disable further argument file expansion\n\n\
|
||||
\ --disable-@files disable further argument file expansion\n\
|
||||
\ --source <version>\n\
|
||||
\ set the version of the source in source-file mode.\n\n\
|
||||
These extra options are subject to change without notice.\n
|
||||
|
||||
# Translators please note do not translate the options themselves
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
|
@ -30,6 +30,7 @@ import java.net.SocketException;
|
|||
import java.net.SocketOption;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Defines the infrastructure to support extended socket options, beyond those
|
||||
|
@ -40,6 +41,9 @@ import java.util.Set;
|
|||
*/
|
||||
public abstract class ExtendedSocketOptions {
|
||||
|
||||
public static final short SOCK_STREAM = 1;
|
||||
public static final short SOCK_DGRAM = 2;
|
||||
|
||||
private final Set<SocketOption<?>> options;
|
||||
|
||||
/** Tells whether or not the option is supported. */
|
||||
|
@ -50,6 +54,30 @@ public abstract class ExtendedSocketOptions {
|
|||
/** Return the, possibly empty, set of extended socket options available. */
|
||||
public final Set<SocketOption<?>> options() { return options; }
|
||||
|
||||
public static final Set<SocketOption<?>> options(short type) {
|
||||
return getInstance().options0(type);
|
||||
}
|
||||
|
||||
private Set<SocketOption<?>> options0(short type) {
|
||||
Set<SocketOption<?>> extOptions = null;
|
||||
switch (type) {
|
||||
case SOCK_DGRAM:
|
||||
extOptions = options.stream()
|
||||
.filter((option) -> !option.name().startsWith("TCP_"))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
break;
|
||||
case SOCK_STREAM:
|
||||
extOptions = options.stream()
|
||||
.filter((option) -> !option.name().startsWith("UDP_"))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
break;
|
||||
default:
|
||||
//this will never happen
|
||||
throw new IllegalArgumentException("Invalid socket option type");
|
||||
}
|
||||
return extOptions;
|
||||
}
|
||||
|
||||
/** Sets the value of a socket option, for the given socket. */
|
||||
public abstract void setOption(FileDescriptor fd, SocketOption<?> option, Object value)
|
||||
throws SocketException;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
|
@ -39,6 +39,8 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import sun.net.NetHooks;
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
|
||||
|
||||
/**
|
||||
* Base implementation of AsynchronousServerSocketChannel.
|
||||
|
@ -234,6 +236,7 @@ abstract class AsynchronousServerSocketChannelImpl
|
|||
if (Net.isReusePortAvailable()) {
|
||||
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||
}
|
||||
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
|
@ -40,6 +40,7 @@ import java.util.concurrent.*;
|
|||
import java.util.concurrent.locks.*;
|
||||
import sun.net.NetHooks;
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
|
||||
|
||||
/**
|
||||
* Base implementation of AsynchronousSocketChannel
|
||||
|
@ -512,9 +513,7 @@ abstract class AsynchronousSocketChannelImpl
|
|||
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||
}
|
||||
set.add(StandardSocketOptions.TCP_NODELAY);
|
||||
ExtendedSocketOptions extendedOptions =
|
||||
ExtendedSocketOptions.getInstance();
|
||||
set.addAll(extendedOptions.options());
|
||||
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||
|
||||
import sun.net.ResourceManager;
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
import static sun.net.ext.ExtendedSocketOptions.SOCK_DGRAM;
|
||||
|
||||
/**
|
||||
* An implementation of DatagramChannels.
|
||||
|
@ -334,7 +335,7 @@ class DatagramChannelImpl
|
|||
set.add(StandardSocketOptions.IP_MULTICAST_IF);
|
||||
set.add(StandardSocketOptions.IP_MULTICAST_TTL);
|
||||
set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
|
||||
set.addAll(ExtendedSocketOptions.getInstance().options());
|
||||
set.addAll(ExtendedSocketOptions.options(SOCK_DGRAM));
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
package sun.nio.ch;
|
||||
|
||||
import java.lang.invoke.ConstantBootstraps;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
|
@ -39,6 +42,13 @@ import java.nio.channels.spi.AbstractSelectionKey;
|
|||
public final class SelectionKeyImpl
|
||||
extends AbstractSelectionKey
|
||||
{
|
||||
private static final VarHandle INTERESTOPS =
|
||||
ConstantBootstraps.fieldVarHandle(
|
||||
MethodHandles.lookup(),
|
||||
"interestOps",
|
||||
VarHandle.class,
|
||||
SelectionKeyImpl.class, int.class);
|
||||
|
||||
private final SelChImpl channel;
|
||||
private final SelectorImpl selector;
|
||||
|
||||
|
@ -84,7 +94,35 @@ public final class SelectionKeyImpl
|
|||
@Override
|
||||
public SelectionKey interestOps(int ops) {
|
||||
ensureValid();
|
||||
return nioInterestOps(ops);
|
||||
if ((ops & ~channel().validOps()) != 0)
|
||||
throw new IllegalArgumentException();
|
||||
int oldOps = (int) INTERESTOPS.getAndSet(this, ops);
|
||||
if (ops != oldOps) {
|
||||
selector.setEventOps(this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int interestOpsOr(int ops) {
|
||||
ensureValid();
|
||||
if ((ops & ~channel().validOps()) != 0)
|
||||
throw new IllegalArgumentException();
|
||||
int oldVal = (int) INTERESTOPS.getAndBitwiseOr(this, ops);
|
||||
if (oldVal != (oldVal | ops)) {
|
||||
selector.setEventOps(this);
|
||||
}
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int interestOpsAnd(int ops) {
|
||||
ensureValid();
|
||||
int oldVal = (int) INTERESTOPS.getAndBitwiseAnd(this, ops);
|
||||
if (oldVal != (oldVal & ops)) {
|
||||
selector.setEventOps(this);
|
||||
}
|
||||
return oldVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -49,6 +49,8 @@ import java.util.Set;
|
|||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import sun.net.NetHooks;
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
|
||||
|
||||
/**
|
||||
* An implementation of ServerSocketChannels
|
||||
|
@ -199,6 +201,7 @@ class ServerSocketChannelImpl
|
|||
set.add(StandardSocketOptions.SO_REUSEPORT);
|
||||
}
|
||||
set.add(StandardSocketOptions.IP_TOS);
|
||||
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||
|
||||
import sun.net.NetHooks;
|
||||
import sun.net.ext.ExtendedSocketOptions;
|
||||
import static sun.net.ext.ExtendedSocketOptions.SOCK_STREAM;
|
||||
|
||||
/**
|
||||
* An implementation of SocketChannels
|
||||
|
@ -280,7 +281,7 @@ class SocketChannelImpl
|
|||
// additional options required by socket adaptor
|
||||
set.add(StandardSocketOptions.IP_TOS);
|
||||
set.add(ExtendedSocketOption.SO_OOBINLINE);
|
||||
set.addAll(ExtendedSocketOptions.getInstance().options());
|
||||
set.addAll(ExtendedSocketOptions.options(SOCK_STREAM));
|
||||
return Collections.unmodifiableSet(set);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 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
|
||||
|
@ -106,6 +106,7 @@ public class FormatData extends ParallelListResourceBundle {
|
|||
"T",
|
||||
"S",
|
||||
"H",
|
||||
"N", // NewEra
|
||||
};
|
||||
|
||||
// Japanese imperial calendar era strings
|
||||
|
@ -115,6 +116,7 @@ public class FormatData extends ParallelListResourceBundle {
|
|||
"Taisho",
|
||||
"Showa",
|
||||
"Heisei",
|
||||
"NewEra", // NewEra
|
||||
};
|
||||
|
||||
return new Object[][] {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 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
|
||||
|
@ -159,6 +159,7 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
|||
"Taisho",
|
||||
"Showa",
|
||||
"Heisei",
|
||||
"NewEra", // New Era
|
||||
};
|
||||
|
||||
final String[] sharedShortEras = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
|
@ -48,6 +48,7 @@ import java.util.TimeZone;
|
|||
* Taisho 1912-07-30T00:00:00 local time
|
||||
* Showa 1926-12-25T00:00:00 local time
|
||||
* Heisei 1989-01-08T00:00:00 local time
|
||||
* NewEra 2019-05-01T00:00:00 local time
|
||||
* -----------------------------------------------------------------------
|
||||
* }</pre>
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 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
|
||||
|
@ -27,6 +27,8 @@ package sun.util.calendar;
|
|||
|
||||
import java.security.AccessController;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
|
@ -41,11 +43,12 @@ public class LocalGregorianCalendar extends BaseCalendar {
|
|||
new Era("Taisho", "T", -1812153600000L, true),
|
||||
new Era("Showa", "S", -1357603200000L, true),
|
||||
new Era("Heisei", "H", 600220800000L, true),
|
||||
new Era("NewEra", "N", 1556668800000L, true),
|
||||
};
|
||||
|
||||
private static boolean isValidEra(Era newEra, Era[] eras) {
|
||||
Era last = eras[eras.length - 1];
|
||||
if (last.getSinceDate().getYear() >= newEra.getSinceDate().getYear()) {
|
||||
if (last.getSince(null) >= newEra.getSince(null)) {
|
||||
return false;
|
||||
}
|
||||
// The new era name should be unique. Its abbr may not.
|
||||
|
@ -173,7 +176,7 @@ public class LocalGregorianCalendar extends BaseCalendar {
|
|||
return null;
|
||||
}
|
||||
String key = keyvalue[0].trim();
|
||||
String value = keyvalue[1].trim();
|
||||
String value = convertUnicodeEscape(keyvalue[1].trim());
|
||||
switch (key) {
|
||||
case "name":
|
||||
eraName = value;
|
||||
|
@ -203,6 +206,17 @@ public class LocalGregorianCalendar extends BaseCalendar {
|
|||
return new Era(eraName, abbr, since, localTime);
|
||||
}
|
||||
|
||||
private static String convertUnicodeEscape(String src) {
|
||||
Matcher m = Pattern.compile("\\\\u([0-9a-fA-F]{4})").matcher(src);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (m.find()) {
|
||||
m.appendReplacement(sb,
|
||||
Character.toString((char)Integer.parseUnsignedInt(m.group(1), 16)));
|
||||
}
|
||||
m.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private LocalGregorianCalendar(String name, Era[] eras) {
|
||||
this.name = name;
|
||||
this.eras = eras;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
|
@ -35,8 +35,8 @@ import sun.util.calendar.CalendarSystem;
|
|||
import sun.util.calendar.Era;
|
||||
|
||||
/**
|
||||
* Concrete implementation of the {@link java.util.spi.CalendarDataProvider
|
||||
* CalendarDataProvider} class for the JRE LocaleProviderAdapter.
|
||||
* Concrete implementation of the {@link java.util.spi.CalendarNameProvider
|
||||
* CalendarNameProvider} class for the JRE LocaleProviderAdapter.
|
||||
*
|
||||
* @author Masayoshi Okutsu
|
||||
* @author Naoto Sato
|
||||
|
@ -77,28 +77,43 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
if (field == DAY_OF_WEEK || field == YEAR) {
|
||||
--value;
|
||||
}
|
||||
if (value < 0 || value > strings.length) {
|
||||
if (value < 0) {
|
||||
return null;
|
||||
} else if (value == strings.length) {
|
||||
} else if (value >= strings.length) {
|
||||
if (field == ERA && "japanese".equals(calendarType)) {
|
||||
// get the supplemental era, if any, specified through
|
||||
// the property "jdk.calendar.japanese.supplemental.era"
|
||||
// which is always the last element.
|
||||
Era[] jeras = CalendarSystem.forName("japanese").getEras();
|
||||
if (jeras.length == value) {
|
||||
Era supEra = jeras[value - 1]; // 0-based index
|
||||
if (javatime) {
|
||||
return getBaseStyle(style) == NARROW_FORMAT ?
|
||||
supEra.getAbbreviation() :
|
||||
supEra.getName();
|
||||
} else {
|
||||
return (style & LONG) != 0 ?
|
||||
supEra.getName() :
|
||||
supEra.getAbbreviation();
|
||||
if (value <= jeras.length) {
|
||||
// Localized era name could not be retrieved from this provider.
|
||||
// This can occur either for NewEra or SupEra.
|
||||
//
|
||||
// If it's CLDR provider, try COMPAT first, which is guaranteed to have
|
||||
// the name for NewEra.
|
||||
if (type == LocaleProviderAdapter.Type.CLDR) {
|
||||
lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
|
||||
key = getResourceKeyFor(LocaleProviderAdapter.Type.JRE,
|
||||
calendarType, field, style, javatime);
|
||||
strings =
|
||||
javatime ? lr.getJavaTimeNames(key) : lr.getCalendarNames(key);
|
||||
}
|
||||
if (strings == null || value >= strings.length) {
|
||||
// Get the default name for SupEra
|
||||
Era supEra = jeras[value - 1]; // 0-based index
|
||||
if (javatime) {
|
||||
return getBaseStyle(style) == NARROW_FORMAT ?
|
||||
supEra.getAbbreviation() :
|
||||
supEra.getName();
|
||||
} else {
|
||||
return (style & LONG) != 0 ?
|
||||
supEra.getName() :
|
||||
supEra.getAbbreviation();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
name = strings[value];
|
||||
// If name is empty in standalone, try its `format' style.
|
||||
|
@ -180,7 +195,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
return map;
|
||||
}
|
||||
|
||||
private int getBaseStyle(int style) {
|
||||
private static int getBaseStyle(int style) {
|
||||
return style & ~(SHORT_STANDALONE - SHORT_FORMAT);
|
||||
}
|
||||
|
||||
|
@ -261,6 +276,11 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
}
|
||||
|
||||
private String getResourceKey(String type, int field, int style, boolean javatime) {
|
||||
return getResourceKeyFor(this.type, type, field, style, javatime);
|
||||
}
|
||||
|
||||
private static String getResourceKeyFor(LocaleProviderAdapter.Type adapterType,
|
||||
String type, int field, int style, boolean javatime) {
|
||||
int baseStyle = getBaseStyle(style);
|
||||
boolean isStandalone = (style != baseStyle);
|
||||
|
||||
|
@ -284,7 +304,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
// JRE and CLDR use different resource key conventions
|
||||
// due to historical reasons. (JRE DateFormatSymbols.getEras returns
|
||||
// abbreviations while other getShort*() return abbreviations.)
|
||||
if (this.type == LocaleProviderAdapter.Type.JRE) {
|
||||
if (adapterType == LocaleProviderAdapter.Type.JRE) {
|
||||
if (javatime) {
|
||||
if (baseStyle == LONG) {
|
||||
key.append("long.");
|
||||
|
@ -336,7 +356,7 @@ public class CalendarNameProviderImpl extends CalendarNameProvider implements Av
|
|||
return key.length() > 0 ? key.toString() : null;
|
||||
}
|
||||
|
||||
private String toStyleName(int baseStyle) {
|
||||
private static String toStyleName(int baseStyle) {
|
||||
switch (baseStyle) {
|
||||
case SHORT:
|
||||
return "Abbreviations";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 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
|
||||
|
@ -178,6 +178,7 @@ MMK=MMK
|
|||
MNT=MNT
|
||||
MOP=MOP
|
||||
MRO=MRO
|
||||
MRU=MRU
|
||||
MTL=MTL
|
||||
MUR=MUR
|
||||
MVR=MVR
|
||||
|
@ -399,6 +400,7 @@ mmk=Myanma Kyat
|
|||
mnt=Mongolian Tugrik
|
||||
mop=Macanese Pataca
|
||||
mro=Mauritanian Ouguiya
|
||||
mru=Mauritanian Ouguiya
|
||||
mtl=Maltese Lira
|
||||
mur=Mauritian Rupee
|
||||
mvr=Maldivian Rufiyaa
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue