8356985: Use "stdin.encoding" in Console's read*() methods
Reviewed-by: jlu, smarks, alanb, vyazici
This commit is contained in:
parent
8949c07484
commit
b2a61a9972
@ -59,6 +59,13 @@ import sun.nio.cs.UTF_8;
|
|||||||
* on the objects returned by {@link #reader()} and {@link #writer()} may
|
* on the objects returned by {@link #reader()} and {@link #writer()} may
|
||||||
* block in multithreaded scenarios.
|
* block in multithreaded scenarios.
|
||||||
* <p>
|
* <p>
|
||||||
|
* Read and write operations use the {@code Charset}s specified by
|
||||||
|
* {@link System##stdin.encoding stdin.encoding} and {@link
|
||||||
|
* System##stdout.encoding stdout.encoding}, respectively. The
|
||||||
|
* {@code Charset} used for write operations can also be retrieved using
|
||||||
|
* the {@link #charset()} method. Since {@code Console} is intended for
|
||||||
|
* interactive use on a terminal, these charsets are typically the same.
|
||||||
|
* <p>
|
||||||
* Operations that format strings are locale sensitive, using either the
|
* Operations that format strings are locale sensitive, using either the
|
||||||
* specified {@code Locale}, or the
|
* specified {@code Locale}, or the
|
||||||
* {@link Locale##default_locale default format Locale} to produce localized
|
* {@link Locale##default_locale default format Locale} to produce localized
|
||||||
@ -509,17 +516,15 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link java.nio.charset.Charset Charset} object used for
|
* {@return the {@link java.nio.charset.Charset Charset} object used for
|
||||||
* the {@code Console}.
|
* the write operations on this {@code Console}}
|
||||||
* <p>
|
* <p>
|
||||||
* The returned charset is used for interpreting the input and output source
|
* The returned charset is used for encoding the data that is sent to
|
||||||
* (e.g., keyboard and/or display) specified by the host environment or user,
|
* the output (e.g., display), specified by the host environment or user.
|
||||||
* which defaults to the one based on {@link System##stdout.encoding stdout.encoding}.
|
* It defaults to the one based on {@link System##stdout.encoding stdout.encoding},
|
||||||
* It may not necessarily be the same as the default charset returned from
|
* and may not necessarily be the same as the default charset returned from
|
||||||
* {@link java.nio.charset.Charset#defaultCharset() Charset.defaultCharset()}.
|
* {@link java.nio.charset.Charset#defaultCharset() Charset.defaultCharset()}.
|
||||||
*
|
*
|
||||||
* @return a {@link java.nio.charset.Charset Charset} object used for the
|
|
||||||
* {@code Console}
|
|
||||||
* @since 17
|
* @since 17
|
||||||
*/
|
*/
|
||||||
public Charset charset() {
|
public Charset charset() {
|
||||||
@ -549,7 +554,9 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean istty = istty();
|
private static final boolean istty = istty();
|
||||||
static final Charset CHARSET =
|
private static final Charset STDIN_CHARSET =
|
||||||
|
Charset.forName(System.getProperty("stdin.encoding"), UTF_8.INSTANCE);
|
||||||
|
private static final Charset STDOUT_CHARSET =
|
||||||
Charset.forName(System.getProperty("stdout.encoding"), UTF_8.INSTANCE);
|
Charset.forName(System.getProperty("stdout.encoding"), UTF_8.INSTANCE);
|
||||||
private static final Console cons = instantiateConsole();
|
private static final Console cons = instantiateConsole();
|
||||||
static {
|
static {
|
||||||
@ -579,7 +586,7 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
|||||||
|
|
||||||
for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) {
|
for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) {
|
||||||
if (consModName.equals(jcp.getClass().getModule().getName())) {
|
if (consModName.equals(jcp.getClass().getModule().getName())) {
|
||||||
var jc = jcp.console(istty, CHARSET);
|
var jc = jcp.console(istty, STDIN_CHARSET, STDOUT_CHARSET);
|
||||||
if (jc != null) {
|
if (jc != null) {
|
||||||
c = new ProxyingConsole(jc);
|
c = new ProxyingConsole(jc);
|
||||||
}
|
}
|
||||||
@ -591,7 +598,7 @@ public sealed class Console implements Flushable permits ProxyingConsole {
|
|||||||
|
|
||||||
// If not found, default to built-in Console
|
// If not found, default to built-in Console
|
||||||
if (istty && c == null) {
|
if (istty && c == null) {
|
||||||
c = new ProxyingConsole(new JdkConsoleImpl(CHARSET));
|
c = new ProxyingConsole(new JdkConsoleImpl(STDIN_CHARSET, STDOUT_CHARSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
@ -191,10 +191,11 @@ public final class JdkConsoleImpl implements JdkConsole {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Charset charset() {
|
public Charset charset() {
|
||||||
return charset;
|
return outCharset;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Charset charset;
|
private final Charset inCharset;
|
||||||
|
private final Charset outCharset;
|
||||||
private final Object readLock;
|
private final Object readLock;
|
||||||
private final Object writeLock;
|
private final Object writeLock;
|
||||||
// Must not block while holding this. It is used in the shutdown hook.
|
// Must not block while holding this. It is used in the shutdown hook.
|
||||||
@ -364,16 +365,18 @@ public final class JdkConsoleImpl implements JdkConsole {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JdkConsoleImpl(Charset charset) {
|
public JdkConsoleImpl(Charset inCharset, Charset outCharset) {
|
||||||
Objects.requireNonNull(charset);
|
Objects.requireNonNull(inCharset);
|
||||||
this.charset = charset;
|
Objects.requireNonNull(outCharset);
|
||||||
|
this.inCharset = inCharset;
|
||||||
|
this.outCharset = outCharset;
|
||||||
readLock = new Object();
|
readLock = new Object();
|
||||||
writeLock = new Object();
|
writeLock = new Object();
|
||||||
restoreEchoLock = new Object();
|
restoreEchoLock = new Object();
|
||||||
out = StreamEncoder.forOutputStreamWriter(
|
out = StreamEncoder.forOutputStreamWriter(
|
||||||
new FileOutputStream(FileDescriptor.out),
|
new FileOutputStream(FileDescriptor.out),
|
||||||
writeLock,
|
writeLock,
|
||||||
charset);
|
outCharset);
|
||||||
pw = new PrintWriter(out, true) {
|
pw = new PrintWriter(out, true) {
|
||||||
public void close() {
|
public void close() {
|
||||||
}
|
}
|
||||||
@ -382,7 +385,7 @@ public final class JdkConsoleImpl implements JdkConsole {
|
|||||||
reader = new LineReader(StreamDecoder.forInputStreamReader(
|
reader = new LineReader(StreamDecoder.forInputStreamReader(
|
||||||
new FileInputStream(FileDescriptor.in),
|
new FileInputStream(FileDescriptor.in),
|
||||||
readLock,
|
readLock,
|
||||||
charset));
|
inCharset));
|
||||||
rcb = new char[1024];
|
rcb = new char[1024];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@ public interface JdkConsoleProvider {
|
|||||||
/**
|
/**
|
||||||
* {@return the Console instance, or {@code null} if not available}
|
* {@return the Console instance, or {@code null} if not available}
|
||||||
* @param isTTY indicates if the jvm is attached to a terminal
|
* @param isTTY indicates if the jvm is attached to a terminal
|
||||||
* @param charset charset of the platform console
|
* @param inCharset Standard input charset of the platform console
|
||||||
|
* @param outCharset Standard output charset of the platform console
|
||||||
*/
|
*/
|
||||||
JdkConsole console(boolean isTTY, Charset charset);
|
JdkConsole console(boolean isTTY, Charset inCharset, Charset outCharset);
|
||||||
}
|
}
|
||||||
|
@ -49,18 +49,18 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public JdkConsole console(boolean isTTY, Charset charset) {
|
public JdkConsole console(boolean isTTY, Charset inCharset, Charset outCharset) {
|
||||||
return new LazyDelegatingJdkConsoleImpl(charset);
|
return new LazyDelegatingJdkConsoleImpl(inCharset, outCharset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class LazyDelegatingJdkConsoleImpl implements JdkConsole {
|
private static class LazyDelegatingJdkConsoleImpl implements JdkConsole {
|
||||||
private final Charset charset;
|
private final Charset outCharset;
|
||||||
private volatile boolean jlineInitialized;
|
private volatile boolean jlineInitialized;
|
||||||
private volatile JdkConsole delegate;
|
private volatile JdkConsole delegate;
|
||||||
|
|
||||||
public LazyDelegatingJdkConsoleImpl(Charset charset) {
|
public LazyDelegatingJdkConsoleImpl(Charset inCharset, Charset outCharset) {
|
||||||
this.charset = charset;
|
this.outCharset = outCharset;
|
||||||
this.delegate = new jdk.internal.io.JdkConsoleImpl(charset);
|
this.delegate = new jdk.internal.io.JdkConsoleImpl(inCharset, outCharset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -130,7 +130,7 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Charset charset() {
|
public Charset charset() {
|
||||||
return charset;
|
return outCharset;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushOldDelegateIfNeeded(JdkConsole oldDelegate) {
|
private void flushOldDelegateIfNeeded(JdkConsole oldDelegate) {
|
||||||
@ -157,7 +157,7 @@ public class JdkConsoleProviderImpl implements JdkConsoleProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Terminal terminal = TerminalBuilder.builder().encoding(charset)
|
Terminal terminal = TerminalBuilder.builder().encoding(outCharset)
|
||||||
.exec(false)
|
.exec(false)
|
||||||
.nativeSignals(false)
|
.nativeSignals(false)
|
||||||
.systemOutput(SystemOutput.SysOut)
|
.systemOutput(SystemOutput.SysOut)
|
||||||
|
@ -64,7 +64,7 @@ public class ConsoleImpl {
|
|||||||
private static RemoteConsole console;
|
private static RemoteConsole console;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JdkConsole console(boolean isTTY, Charset charset) {
|
public JdkConsole console(boolean isTTY, Charset inCharset, Charset outCharset) {
|
||||||
synchronized (ConsoleProviderImpl.class) {
|
synchronized (ConsoleProviderImpl.class) {
|
||||||
if (remoteOutput != null && remoteInput != null) {
|
if (remoteOutput != null && remoteInput != null) {
|
||||||
return console = new RemoteConsole(remoteOutput, remoteInput);
|
return console = new RemoteConsole(remoteOutput, remoteInput);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,10 +27,11 @@ import java.nio.file.Paths;
|
|||||||
|
|
||||||
import jdk.test.lib.process.OutputAnalyzer;
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
import jdk.test.lib.process.ProcessTools;
|
import jdk.test.lib.process.ProcessTools;
|
||||||
|
import static jdk.test.lib.Utils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 8264208 8265918
|
* @bug 8264208 8265918 8356985
|
||||||
* @summary Tests Console.charset() method. "expect" command in Windows/Cygwin
|
* @summary Tests Console.charset() method. "expect" command in Windows/Cygwin
|
||||||
* does not work as expected. Ignoring tests on Windows.
|
* does not work as expected. Ignoring tests on Windows.
|
||||||
* @requires (os.family == "linux") | (os.family == "mac")
|
* @requires (os.family == "linux") | (os.family == "mac")
|
||||||
@ -50,22 +51,18 @@ public class CharsetTest {
|
|||||||
// check "expect" command availability
|
// check "expect" command availability
|
||||||
var expect = Paths.get("/usr/bin/expect");
|
var expect = Paths.get("/usr/bin/expect");
|
||||||
if (!Files.exists(expect) || !Files.isExecutable(expect)) {
|
if (!Files.exists(expect) || !Files.isExecutable(expect)) {
|
||||||
System.out.println("'expect' command not found. Test ignored.");
|
throw new jtreg.SkippedException("'expect' command not found. Test ignored.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// invoking "expect" command
|
// invoking "expect" command
|
||||||
var testSrc = System.getProperty("test.src", ".");
|
|
||||||
var testClasses = System.getProperty("test.classes", ".");
|
|
||||||
var jdkDir = System.getProperty("test.jdk");
|
|
||||||
OutputAnalyzer output = ProcessTools.executeProcess(
|
OutputAnalyzer output = ProcessTools.executeProcess(
|
||||||
"expect",
|
"expect",
|
||||||
"-n",
|
"-n",
|
||||||
testSrc + "/script.exp",
|
TEST_SRC + "/script.exp",
|
||||||
jdkDir + "/bin/java",
|
TEST_JDK + "/bin/java",
|
||||||
args[0],
|
args[0],
|
||||||
args[1],
|
args[1],
|
||||||
testClasses);
|
TEST_CLASSES);
|
||||||
output.reportDiagnosticSummary();
|
output.reportDiagnosticSummary();
|
||||||
var eval = output.getExitValue();
|
var eval = output.getExitValue();
|
||||||
if (eval != 0) {
|
if (eval != 0) {
|
||||||
|
92
test/jdk/java/io/Console/StdinEncodingTest.java
Normal file
92
test/jdk/java/io/Console/StdinEncodingTest.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025, 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
import jdk.test.lib.process.ProcessTools;
|
||||||
|
import static jdk.test.lib.Utils.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assumptions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8356985
|
||||||
|
* @summary Tests if "stdin.encoding" is reflected for reading
|
||||||
|
* the console. "expect" command in Windows/Cygwin does
|
||||||
|
* not work as expected. Ignoring tests on Windows.
|
||||||
|
* @requires (os.family == "linux" | os.family == "mac")
|
||||||
|
* @library /test/lib
|
||||||
|
* @build csp/*
|
||||||
|
* @run junit StdinEncodingTest
|
||||||
|
*/
|
||||||
|
public class StdinEncodingTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStdinEncoding() throws Throwable {
|
||||||
|
// check "expect" command availability
|
||||||
|
var expect = Paths.get("/usr/bin/expect");
|
||||||
|
Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect),
|
||||||
|
"'" + expect + "' not found");
|
||||||
|
|
||||||
|
// invoking "expect" command
|
||||||
|
OutputAnalyzer output = ProcessTools.executeProcess(
|
||||||
|
"expect",
|
||||||
|
"-n",
|
||||||
|
TEST_SRC + "/stdinEncoding.exp",
|
||||||
|
TEST_JDK + "/bin/java",
|
||||||
|
"--module-path",
|
||||||
|
TEST_CLASSES + "/modules",
|
||||||
|
"-Dstdin.encoding=Uppercasing", // <- gist of this test
|
||||||
|
"StdinEncodingTest");
|
||||||
|
output.reportDiagnosticSummary();
|
||||||
|
var eval = output.getExitValue();
|
||||||
|
assertEquals(0, eval, "Test failed. Exit value from 'expect' command: " + eval);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String... args) throws Throwable {
|
||||||
|
// check stdin.encoding
|
||||||
|
if (!"Uppercasing".equals(System.getProperty("stdin.encoding"))) {
|
||||||
|
throw new RuntimeException("Uppercasing charset was not set in stdin.encoding");
|
||||||
|
}
|
||||||
|
var con = System.console();
|
||||||
|
|
||||||
|
// Console.readLine()
|
||||||
|
System.out.print(con.readLine());
|
||||||
|
|
||||||
|
// Console.readPassword()
|
||||||
|
System.out.print(String.valueOf(con.readPassword()));
|
||||||
|
|
||||||
|
// Console.reader()
|
||||||
|
try (var br = new BufferedReader(con.reader())) {
|
||||||
|
System.out.print(br.readLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait till the test receives the result
|
||||||
|
con.readLine();
|
||||||
|
}
|
||||||
|
}
|
26
test/jdk/java/io/Console/csp/module-info.java
Normal file
26
test/jdk/java/io/Console/csp/module-info.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025, 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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module csp {
|
||||||
|
provides java.nio.charset.spi.CharsetProvider with provider.UppercasingCharsetProvider;
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025, 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.
|
||||||
|
*
|
||||||
|
* 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 provider;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.CharsetDecoder;
|
||||||
|
import java.nio.charset.CharsetEncoder;
|
||||||
|
import java.nio.charset.CoderResult;
|
||||||
|
import java.nio.charset.spi.CharsetProvider;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
// A test charset provider that decodes every input byte into its uppercase
|
||||||
|
public class UppercasingCharsetProvider extends CharsetProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator charsets() {
|
||||||
|
return Collections.singleton(new UppercasingCharsetProvider.UppercasingCharset()).iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Charset charsetForName(String charsetName) {
|
||||||
|
if (charsetName.equals("Uppercasing")) {
|
||||||
|
return new UppercasingCharsetProvider.UppercasingCharset();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UppercasingCharset extends Charset {
|
||||||
|
|
||||||
|
public UppercasingCharset() {
|
||||||
|
super("Uppercasing", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Charset cs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharsetDecoder newDecoder() {
|
||||||
|
return new UppercasingCharsetDecoder(this, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharsetEncoder newEncoder() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UppercasingCharsetDecoder extends CharsetDecoder {
|
||||||
|
public UppercasingCharsetDecoder(Charset cs, float averageCharsPerByte, float maxCharsPerByte) {
|
||||||
|
super(cs, averageCharsPerByte, maxCharsPerByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
|
||||||
|
while (in.remaining() > 0) {
|
||||||
|
out.put(Character.toUpperCase((char)in.get()));
|
||||||
|
}
|
||||||
|
return CoderResult.UNDERFLOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# This code is free software; you can redistribute it and/or modify it
|
||||||
@ -27,6 +27,6 @@ set expected [lrange $argv 2 2]
|
|||||||
set args [lrange $argv 3 end]
|
set args [lrange $argv 3 end]
|
||||||
regexp {([a-zA-Z_]*).([a-zA-Z0-9\-]*)} $locale dummy lang_region encoding
|
regexp {([a-zA-Z_]*).([a-zA-Z0-9\-]*)} $locale dummy lang_region encoding
|
||||||
|
|
||||||
eval spawn $java -Dsun.stdout.encoding=$encoding -classpath $args CharsetTest
|
eval spawn $java -Dstdout.encoding=$encoding -classpath $args CharsetTest
|
||||||
expect $expected
|
expect $expected
|
||||||
expect eof
|
expect eof
|
||||||
|
63
test/jdk/java/io/Console/stdinEncoding.exp
Normal file
63
test/jdk/java/io/Console/stdinEncoding.exp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2025, 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.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
set java [lrange $argv 0 end]
|
||||||
|
|
||||||
|
eval spawn $java
|
||||||
|
|
||||||
|
# Console::readLine()
|
||||||
|
send "abc\r"
|
||||||
|
expect {
|
||||||
|
"ABC" { send_error "Console::readLine() received\n" }
|
||||||
|
timeout {
|
||||||
|
send_error "Error: Console::readLine() not received\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Console::readPassword()
|
||||||
|
send "def\r"
|
||||||
|
expect {
|
||||||
|
"DEF" { send_error "Console::readPassword() received\n" }
|
||||||
|
timeout {
|
||||||
|
send_error "Error: Console::readPassword() not received\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Console::reader()
|
||||||
|
send "ghi\r"
|
||||||
|
expect {
|
||||||
|
"GHI" { send_error "Console::reader() received\n" }
|
||||||
|
timeout {
|
||||||
|
send_error "Error: Console::reader() not received\n"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# should receive eof
|
||||||
|
send "\r"
|
||||||
|
expect eof
|
||||||
|
|
||||||
|
# success
|
||||||
|
exit 0
|
Loading…
x
Reference in New Issue
Block a user