From e6169cc3cf17ca23e2bd245b0b87f8e16a4b346a Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Mon, 2 Feb 2026 12:02:25 +0000 Subject: [PATCH 01/18] refactor: move codecs package --- .../org/apache/yoko/{orb => }/codecs/CharCodec.java | 6 +++--- .../org/apache/yoko/{orb => }/codecs/LatinCodec.java | 6 +++--- .../apache/yoko/{orb => }/codecs/SimpleCharCodec.java | 8 ++++---- .../apache/yoko/{orb => }/codecs/SimpleWcharCodec.java | 10 +++++----- .../org/apache/yoko/{orb => }/codecs/Utf8Codec.java | 6 +++--- .../java/org/apache/yoko/{orb => }/codecs/Util.java | 2 +- .../org/apache/yoko/{orb => }/codecs/WcharCodec.java | 2 +- .../yoko/{orb => }/codecs/AbstractLatinCodecTest.java | 2 +- .../yoko/{orb => }/codecs/AbstractSimpleCodecTest.java | 8 +++++--- .../apache/yoko/{orb => }/codecs/IsoLatin1Test.java | 4 ++-- .../org/apache/yoko/{orb => }/codecs/TestData.java | 4 ++-- .../org/apache/yoko/{orb => }/codecs/UsAsciiTest.java | 4 ++-- .../org/apache/yoko/{orb => }/codecs/Utf16Test.java | 4 ++-- .../apache/yoko/{orb => }/codecs/Utf8InvalidTest.java | 4 ++-- .../org/apache/yoko/{orb => }/codecs/Utf8Test.java | 6 +++--- 15 files changed, 39 insertions(+), 37 deletions(-) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/CharCodec.java (97%) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/LatinCodec.java (96%) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/SimpleCharCodec.java (85%) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/SimpleWcharCodec.java (92%) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/Utf8Codec.java (98%) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/Util.java (98%) rename yoko-core/src/main/java/org/apache/yoko/{orb => }/codecs/WcharCodec.java (99%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/AbstractLatinCodecTest.java (99%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/AbstractSimpleCodecTest.java (93%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/IsoLatin1Test.java (94%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/TestData.java (96%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/UsAsciiTest.java (94%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/Utf16Test.java (98%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/Utf8InvalidTest.java (98%) rename yoko-core/src/test/java/org/apache/yoko/{orb => }/codecs/Utf8Test.java (97%) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/CharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java similarity index 97% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/CharCodec.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java index afca922b2..54d1bb926 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/CharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java @@ -16,7 +16,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; @@ -27,8 +27,8 @@ import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import static org.apache.yoko.orb.codecs.LatinCodec.getLatinCodec; -import static org.apache.yoko.orb.codecs.Util.getUnicodeCodec; +import static org.apache.yoko.codecs.LatinCodec.getLatinCodec; +import static org.apache.yoko.codecs.Util.getUnicodeCodec; import static org.apache.yoko.util.MinorCodes.MinorUTF8Encoding; import static org.apache.yoko.util.MinorCodes.MinorUTF8Overflow; import static org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/LatinCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java similarity index 96% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/LatinCodec.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java index 1e96b2743..6d5e1d668 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/LatinCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; @@ -32,8 +32,8 @@ import static java.nio.ByteBuffer.allocate; import static java.util.Collections.unmodifiableMap; import static java.util.stream.IntStream.range; -import static org.apache.yoko.orb.codecs.Util.ASCII_REPLACEMENT_BYTE; -import static org.apache.yoko.orb.codecs.Util.UNICODE_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_BYTE; +import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR; import static org.apache.yoko.util.Collectors.neverCombine; /** diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/SimpleCharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java similarity index 85% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/SimpleCharCodec.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java index 2fcb148f9..b4b7305bb 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/SimpleCharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java @@ -16,14 +16,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; -import static org.apache.yoko.orb.codecs.Util.expect7bit; -import static org.apache.yoko.orb.codecs.Util.require7bit; -import static org.apache.yoko.orb.codecs.Util.require8bit; +import static org.apache.yoko.codecs.Util.expect7bit; +import static org.apache.yoko.codecs.Util.require7bit; +import static org.apache.yoko.codecs.Util.require8bit; enum SimpleCharCodec implements CharCodec { US_ASCII { diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/SimpleWcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java similarity index 92% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/SimpleWcharCodec.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java index adc240da3..90a524fee 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/SimpleWcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java @@ -15,16 +15,16 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; import static org.apache.yoko.logging.VerboseLogging.DATA_IN_LOG; -import static org.apache.yoko.orb.codecs.Util.BYTE_ORDER_MARKER; -import static org.apache.yoko.orb.codecs.Util.BYTE_SWAPD_MARKER; -import static org.apache.yoko.orb.codecs.Util.UNICODE_REPLACEMENT_CHAR; -import static org.apache.yoko.orb.codecs.Util.ZERO_WIDTH_NO_BREAK_SPACE; +import static org.apache.yoko.codecs.Util.BYTE_ORDER_MARKER; +import static org.apache.yoko.codecs.Util.BYTE_SWAPD_MARKER; +import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.ZERO_WIDTH_NO_BREAK_SPACE; enum SimpleWcharCodec implements WcharCodec { UTF_16 { diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java similarity index 98% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/Utf8Codec.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java index 4ac6aecbd..4f382847b 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/Utf8Codec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; @@ -29,8 +29,8 @@ import static java.util.logging.Level.WARNING; import static org.apache.yoko.logging.VerboseLogging.DATA_IN_LOG; import static org.apache.yoko.logging.VerboseLogging.DATA_OUT_LOG; -import static org.apache.yoko.orb.codecs.Util.ASCII_REPLACEMENT_BYTE; -import static org.apache.yoko.orb.codecs.Util.UNICODE_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_BYTE; +import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR; import static org.apache.yoko.util.MinorCodes.MinorUTF8Encoding; import static org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/Util.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java similarity index 98% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/Util.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/Util.java index a5d7a35bd..37b527c2c 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/Util.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; enum Util { ; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/WcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java similarity index 99% rename from yoko-core/src/main/java/org/apache/yoko/orb/codecs/WcharCodec.java rename to yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java index b99e5fa2c..f669a226a 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/codecs/WcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java @@ -16,7 +16,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/AbstractLatinCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java similarity index 99% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/AbstractLatinCodecTest.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java index e2fdb5121..d7f71fe3c 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/AbstractLatinCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/AbstractSimpleCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java similarity index 93% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/AbstractSimpleCodecTest.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java index 44ad709f5..123305ce4 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/AbstractSimpleCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java @@ -15,15 +15,17 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; +import org.apache.yoko.codecs.CharCodec; +import org.apache.yoko.codecs.WcharCodec; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; import org.junit.jupiter.api.BeforeEach; -import static org.apache.yoko.orb.codecs.Util.ASCII_REPLACEMENT_CHAR; -import static org.apache.yoko.orb.codecs.Util.UNICODE_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/IsoLatin1Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java similarity index 94% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/IsoLatin1Test.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java index bb41963f0..d2827347e 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/IsoLatin1Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java @@ -15,14 +15,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import static org.apache.yoko.orb.codecs.Util.ASCII_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_CHAR; class IsoLatin1Test extends AbstractSimpleCodecTest implements TestData { IsoLatin1Test() { super("ISO-8859-1", WriteBuffer::writeByte, ReadBuffer::readByteAsChar); } diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/TestData.java b/yoko-core/src/test/java/org/apache/yoko/codecs/TestData.java similarity index 96% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/TestData.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/TestData.java index 9ee8103aa..86def7537 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/TestData.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/TestData.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import java.util.stream.IntStream; import java.util.stream.Stream; diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/UsAsciiTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java similarity index 94% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/UsAsciiTest.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java index 54f8e2cdb..8b3e90efc 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/UsAsciiTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java @@ -15,14 +15,14 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import static org.apache.yoko.orb.codecs.Util.ASCII_REPLACEMENT_CHAR; +import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_CHAR; class UsAsciiTest extends AbstractSimpleCodecTest implements TestData { UsAsciiTest() { super("US-ASCII", WriteBuffer::writeByte, ReadBuffer::readByteAsChar); } diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf16Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java similarity index 98% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf16Test.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java index 06a2a68f1..63a404b7c 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf16Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java @@ -15,12 +15,12 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; -import org.apache.yoko.orb.codecs.CharCodec.CharReader; +import org.apache.yoko.codecs.CharCodec.CharReader; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf8InvalidTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java similarity index 98% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf8InvalidTest.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java index 23511d5da..6ff9cb671 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf8InvalidTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; diff --git a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf8Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java similarity index 97% rename from yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf8Test.java rename to yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java index 109bb96ec..6dec1b4f8 100644 --- a/yoko-core/src/test/java/org/apache/yoko/orb/codecs/Utf8Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package org.apache.yoko.orb.codecs; +package org.apache.yoko.codecs; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; @@ -31,7 +31,7 @@ import static java.lang.Character.MIN_HIGH_SURROGATE; import static java.lang.Character.isSupplementaryCodePoint; import static java.util.stream.IntStream.concat; -import static org.apache.yoko.orb.codecs.TestData.testRange; +import static org.apache.yoko.codecs.TestData.testRange; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; From 5f8e417cc2ec5320875b8c8661e3e79d33e6765b Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Tue, 3 Feb 2026 12:36:59 +0000 Subject: [PATCH 02/18] refactor(codecs): enhance codecs with size counts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add octet count calculation methods to CharCodec and WcharCodec interfaces to support efficient buffer allocation and encoding size prediction. BREAKING CHANGES: - Renamed WcharCodec methods for clarity: - readCharWithLength() → readLengthAndChar() - writeCharWithLength() → writeLengthAndChar() Changes: - Add CharCodec.isFixedWidth() to identify fixed-width encodings - Add CharCodec.charSize() to get octets per char for fixed-width encodings - Add CharCodec.octetCount(char) to calculate encoding size for a character - Add WcharCodec.octetCount(String) to calculate encoding size for strings - Add WcharCodec.octetCountLengthsAndWchars(int) for GIOP 1.2 calculations - Add CharCodec.NULL_CODEC constant for null codec reference - Implement octetCount methods in Utf8Codec with surrogate pair handling - Implement octetCount methods in SimpleWcharCodec (UTF_16 and NULL variants) - Update Utf8Codec to mark isFixedWidth() as false and throw on charSize() - Enhance AbstractSimpleCodecTest to verify octetCount accuracy after writeChar - Add octetCount verification to AbstractLatinCodecTest - Update test cases to use renamed methods (readLengthAndChar, writeLengthAndChar) - Remove unused InternalException constructor in Utf8Codec - Remove obsolete comment from Utf8Test - Fix code formatting in AbstractSimpleCodecTest (interface declarations) - Improve code documentation and comments The new octet count methods enable: - Pre-calculation of buffer sizes before encoding - Validation of encoded data sizes - Better memory allocation strategies - Support for GIOP 1.2 length-prefixed encoding calculations --- .../org/apache/yoko/codecs/CharCodec.java | 26 ++++++++++++++++--- .../apache/yoko/codecs/SimpleWcharCodec.java | 19 +++++++++++--- .../org/apache/yoko/codecs/Utf8Codec.java | 21 +++++++++++++-- .../org/apache/yoko/codecs/WcharCodec.java | 14 ++++++++-- .../yoko/codecs/AbstractLatinCodecTest.java | 1 + .../yoko/codecs/AbstractSimpleCodecTest.java | 10 +++++-- .../org/apache/yoko/codecs/Utf16Test.java | 4 +-- .../java/org/apache/yoko/codecs/Utf8Test.java | 2 -- 8 files changed, 79 insertions(+), 18 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java index 54d1bb926..d23a0503a 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java @@ -81,6 +81,7 @@ */ public interface CharCodec { @FunctionalInterface interface CharReader { char readChar(ReadBuffer in); } + WcharCodec NULL_CODEC = SimpleWcharCodec.NULL_CODEC; /** * Get a char codec instance for the named Java charset. @@ -115,6 +116,27 @@ static CharCodec forRegistryId(int id) throws UnsupportedCharsetException { String name(); + /** + * Returns true iff the encoding always uses the same number of octets per char + */ + default boolean isFixedWidth() { return true; } + + /** + * Returns the number of octets per char iff {@link #isFixedWidth()} returns true + * @throws UnsupportedOperationException for non-fixed-width encodings + */ + default int charSize() { return 1; } + /** + * Read the next char. + * @throws IndexOutOfBoundsException if the buffer does not contain enough bytes to read a single char + */ + char readChar(ReadBuffer in); + + /** + * Gives the number of octets needed to encode the specified char. + */ + default int octetCount(char c) { return 1; } + /** * Encodes a character to a buffer. *

@@ -133,10 +155,6 @@ static CharCodec forRegistryId(int id) throws UnsupportedCharsetException { */ void writeChar(char c, WriteBuffer out); - /** Read the next char */ - char readChar(ReadBuffer in); - - /** * Check there is no unfinished character data. * This is only relevant for encodings that encode diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java index 90a524fee..2c24ab744 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java @@ -28,11 +28,18 @@ enum SimpleWcharCodec implements WcharCodec { UTF_16 { + public int octetCount(String s) { + if (s.startsWith(""+ZERO_WIDTH_NO_BREAK_SPACE)) return 2 * (s.length() + 1); + return 2 * s.length(); + } + + public int octetCountLengthsAndWchars(int numChars) { return 3 * numChars; } + public char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes) { return swapBytes ? in.readChar_LE() : in.readChar(); } - public char readCharWithLength(ReadBuffer in) { + public char readLengthAndChar(ReadBuffer in) { byte len = in.readByte(); switch (len) { case 2: @@ -71,7 +78,7 @@ public void beginToWriteString(char c, WriteBuffer out) { out.writeChar(c); } - public void writeCharWithLength(char c, WriteBuffer out) { + public void writeLengthAndChar(char c, WriteBuffer out) { // Older versions of Yoko ignore the encoded length and just read two bytes anyway. // So, never write a BOM, and stick to two bytes. out.writeByte(2); @@ -86,14 +93,18 @@ public void writeCharWithLength(char c, WriteBuffer out) { * e.g. it never writes any lengths or BOMs, so it never reads any lengths or BOMs. */ NULL { + public int octetCount(String s) { return 2 * s.length(); } + + public int octetCountLengthsAndWchars(int numChars) { return 2 * numChars; } + public char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes) { return in.readChar(); } - public char readCharWithLength(ReadBuffer in) { return in.readChar(); } + public char readLengthAndChar(ReadBuffer in) { return in.readChar(); } public CharReader beginToReadString(ReadBuffer in) { return this::readChar; } public void beginToWriteString(char c, WriteBuffer out) { out.writeChar(c); } - public void writeCharWithLength(char c, WriteBuffer out) { out.writeChar(c);} + public void writeLengthAndChar(char c, WriteBuffer out) { out.writeChar(c);} }; } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java index 4f382847b..cd3f86cfe 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java @@ -37,7 +37,6 @@ final class Utf8Codec implements CharCodec { static class InternalException extends Exception { InternalException(String message) { super(message); } - InternalException(String message, Throwable cause) { super(message, cause); } } // These are the minimum acceptable values for the encoding length, indexed by the number of bytes. @@ -46,6 +45,12 @@ static class InternalException extends Exception { private char highSurrogate = 0; private char lowSurrogate = 0; + @Override + public boolean isFixedWidth() { return false; } + + @Override + public int charSize() { throw new UnsupportedOperationException(); } + public char readChar(ReadBuffer in) { // return unread low surrogate char if there is one if (0 != lowSurrogate) try { @@ -84,7 +89,7 @@ public char readChar(ReadBuffer in) { // return the high surrogate FIRST return highSurrogate(codepoint); } catch (Exception e) { - // something went wrong while reading a multi-byte encoding + // something went wrong while reading a multibyte encoding DATA_IN_LOG.log(WARNING, e, () -> String.format("Bad input while reading multi-byte encoding beginning at position 0x%d: 0x%s", pos, in.asHex(pos, in.getPosition()).toUpperCase())); DATA_IN_LOG.fine(in::dumpAllDataWithPosition); // so return a replacement character and set the pointer just past this lead byte @@ -114,6 +119,18 @@ private static int nextByte(ReadBuffer in) throws InternalException { return i & 0x3F; } + @Override + public int octetCount(char c) { + // Surrogate pairs in UTF-16 need 4 bytes in UTF-8. + // When we receive the high surrogate, we write a single char '?', so return 1 + if (isHighSurrogate(c)) return 1; + // Unless received out of order, the low surrogate will need a further 3 bytes. + // The out-of-order case will only need 1 byte for '?'. + if (isLowSurrogate(c)) return highSurrogate == 0 ? 1 : 3; + // if it isn't a surrogate pair, compute the length by bounds-checking. + return getUtf8Len(c); + } + public void writeChar(char c, WriteBuffer out) { try { final int codepoint; diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java index f669a226a..c49f171b4 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java @@ -43,9 +43,19 @@ static WcharCodec forRegistryId(int id) { .orElseThrow(() -> new UnsupportedCharsetException("Charset with registry id " + id + " not supported for wchar")); } + @Override + default int charSize() { return 2; } + @Override default char readChar(ReadBuffer in) { return in.readChar(); } // UTF-16 chars are already in Java format + @Override + default int octetCount(char c) { return 2; } + + int octetCount(String s); + + int octetCountLengthsAndWchars(int numChars); + @Override default void writeChar(char c, WriteBuffer out) { out.writeChar(c); } // Java chars are already in UTF-16 format @@ -64,14 +74,14 @@ static WcharCodec forRegistryId(int id) { * However, it can be 4, if the wchar is preceded by a BOM. * This method should be used to read a BOM and then a wchar, i.e. if the length byte was 4. */ - char readCharWithLength(ReadBuffer in); + char readLengthAndChar(ReadBuffer in); /** * In GIOP 1.2, wchars are preceded by a single octet. * This contains the number of octets in the char is encoding, * including any necessary BOM. */ - void writeCharWithLength(char c, WriteBuffer out); + void writeLengthAndChar(char c, WriteBuffer out); /** * In GIOP 1.2, for UTF-16, there may be a byte-order marker to indicate the endianness of the encoded bytes. diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java index d7f71fe3c..e335a2d2e 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java @@ -72,6 +72,7 @@ public void testDecode(String hex, int b, char expectedChar, byte expectedByte) writeBuffer.writeByte(b); char actual = codec.readChar(readBuffer); assertEquals(expected, actual); + assertEquals(1, codec.octetCount(expected)); } @Test diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java index 123305ce4..3b1b795d8 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java @@ -34,8 +34,8 @@ * @param the type of Codec to test: CharCodec or WcharCodec */ public abstract class AbstractSimpleCodecTest { - @FunctionalInterface interface ExpectedCharWriter { void writeTo(WriteBuffer w, char c); } - @FunctionalInterface interface ExpectedCharReader { char readFrom(ReadBuffer w); } + @FunctionalInterface interface ExpectedCharWriter { void writeTo(WriteBuffer w, char c); } + @FunctionalInterface interface ExpectedCharReader { char readFrom(ReadBuffer w); } private WriteBuffer out; final CODEC codec; final ExpectedCharWriter expectedCharWriter; @@ -70,7 +70,10 @@ void assertDecoding(char c, char expected) { } void assertEncoding(char c, char expected) { + int origPosition = out.getPosition(); codec.writeChar(c, out); + // check the octetCount() matches what was written + assertEquals(out.getPosition() - origPosition, codec.octetCount(c), "bytes written should match octet count"); ReadBuffer in = getReadBuffer(); assertEquals(expected, expectedCharReader.readFrom(in)); codec.assertNoBufferedCharData(); @@ -86,7 +89,10 @@ void assertEncoding(char c, char expected) { void assertEncodingFails(char c) { assertDecoding(c, UNICODE_REPLACEMENT_CHAR); newWriteBuffer(); + int origPosition = out.getPosition(); assertEncoding(c, isDoubleByte() ? UNICODE_REPLACEMENT_CHAR : ASCII_REPLACEMENT_CHAR); + // check the octetCount() matches what was written + assertEquals(out.getPosition() - origPosition, codec.octetCount(c), "bytes written should match octet count"); } abstract boolean isDoubleByte(); diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java index 63a404b7c..cd0ef3a11 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java @@ -114,7 +114,7 @@ void testBomBomLittleEndian() { private void assertEndianCharIs(char expectedChar) { ReadBuffer bomA = getReadBuffer(); - assertEquals(expectedChar, codec.readCharWithLength(bomA)); + assertEquals(expectedChar, codec.readLengthAndChar(bomA)); codec.assertNoBufferedCharData(); assertTrue(bomA.isComplete()); // now skip back 4 bytes and try to read it as the first char of a string @@ -132,7 +132,7 @@ void testBomOnItsOwn() { // then either this was an empty string, or if we are expecting a char // it genuinely is a single ZERO WIDTH NO BREAK SPACE character (also 0xFEFF) ReadBuffer singleBom = getReadBuffer(); - assertEquals(BOM, codec.readCharWithLength(singleBom)); + assertEquals(BOM, codec.readLengthAndChar(singleBom)); assertTrue(singleBom.isComplete()); } diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java index 6dec1b4f8..3c83f45df 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java @@ -77,8 +77,6 @@ static Stream _3_ByteChars() { @ParameterizedTest(name = "Encode 4-byte UTF-8 char: {0} ({2})") @MethodSource("_4_ByteChars") void testEncode4ByteChar(String hex, int codepoint, String c) { checkEncoding(codepoint, c); } - // Invalid UTF-8 tests moved to Utf8InvalidTest.java - private void checkDecoding(int codepoint, String expected) { ByteBuffer bb = UTF_8.encode(expected); ReadBuffer in = out.writeBytes(bb.array(), bb.arrayOffset(), bb.remaining()).trim().newReadBuffer(); From ebc52e978f7a3fff130ac2f6f577dadbfa7277da Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Tue, 3 Feb 2026 16:22:27 +0000 Subject: [PATCH 03/18] feat: use new UTF8-compatible (w)char codecs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the legacy CodeConverter architecture with the new CharCodec/WcharCodec interfaces throughout YokoInputStream and YokoOutputStream, simplifying character encoding logic and improving maintainability. BREAKING CHANGES: - Remove CodeConverterBase, CodeConverterImpl, CodeConverterNone classes - Remove CodeSetReader and CodeSetWriter interfaces - Restructure CodeConverters to use CharCodec/WcharCodec instead of converters - Change CodeConverters.NULL_CONVERTER to CodeConverters.COLLOCATED - Remove conversion/reader/writer flags from stream classes Major changes: - Refactor YokoInputStream to use CharCodec/WcharCodec directly: - Simplify read_char() to use codec.readChar() - Simplify read_wchar() with codec methods based on GIOP version - Simplify read_string() to use codec with proper buffer handling - Simplify read_wstring() with separate methods for GIOP versions - Remove all character conversion and reader flag logic - Simplify array reading methods to use single-char methods - Refactor YokoOutputStream to use CharCodec/WcharCodec directly: - Simplify write_char() to use codec.writeChar() with octetCount - Simplify write_wchar() with codec methods based on GIOP version - Rewrite write_string() with fixed-width and variable-width paths - Rewrite write_wstring() with separate methods for GIOP versions - Remove all character conversion and writer flag logic - Simplify array writing methods to use single-char methods - Remove char bounds checking (now handled by codecs) - Update CodeConverters class: - Replace converter fields with charCodec and wcharCodec - Simplify create() method to use CharCodec.forRegistryId() - Remove CodeSetDatabase.getConverter() calls - Update COLLOCATED constant (formerly NULL_CONVERTER) - Update CharCodec.forRegistryId(): - Add null check with descriptive exception - Add ISO_LATIN_1 case - Delegate to LatinCodec.getLatinCodec() for other cases - Remove unreachable throw statement - Update CodeSetUtil and GIOPConnection: - Use CodeConverters.create() with registry IDs directly - Remove ORBInstance parameter (no longer needed) - Update CollocatedClient: - Use CodeConverters.COLLOCATED instead of NULL_CONVERTER - Clean up imports and formatting: - Remove unused CodeConverter imports - Add CharCodec and WcharCodec imports - Use static import for IntStream.range - Fix typo: "encapsulaton" → "encapsulation" - Improve comment formatting and clarity - Remove redundant comments - Remove unused import in AbstractSimpleCodecTest Performance improvements: - Eliminate redundant conversion checks and flag evaluations - Use codec octetCount() for accurate buffer allocation - Reduce temporary buffer allocations in string operations - Simplify control flow in character encoding/decoding The refactoring maintains backward compatibility at the protocol level while significantly simplifying the internal implementation and improving code clarity. --- .../org/apache/yoko/codecs/CharCodec.java | 5 +- .../yoko/orb/CORBA/YokoInputStream.java | 351 ++++------------ .../yoko/orb/CORBA/YokoOutputStream.java | 390 ++++-------------- .../apache/yoko/orb/OB/CodeConverterBase.java | 139 ------- .../apache/yoko/orb/OB/CodeConverterImpl.java | 53 --- .../apache/yoko/orb/OB/CodeConverterNone.java | 68 --- .../apache/yoko/orb/OB/CodeConverters.java | 71 ++-- .../apache/yoko/orb/OB/CodeSetDatabase.java | 18 +- .../org/apache/yoko/orb/OB/CodeSetUtil.java | 4 +- .../apache/yoko/orb/OB/CollocatedClient.java | 4 +- .../apache/yoko/orb/OB/GIOPConnection.java | 2 +- .../yoko/codecs/AbstractSimpleCodecTest.java | 2 - 12 files changed, 207 insertions(+), 900 deletions(-) delete mode 100644 yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterBase.java delete mode 100644 yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterImpl.java delete mode 100644 yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterNone.java diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java index d23a0503a..4ffce18a2 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java @@ -106,12 +106,13 @@ static CharCodec forName(String name) throws IllegalCharsetNameException, Illega static CharCodec forRegistryId(int id) throws UnsupportedCharsetException { CodeSetInfo csi = CodeSetInfo.forRegistryId(id); + if (null == csi) throw new UnsupportedCharsetException(String.format("Unknown registry id: 0x%08x", id)); switch (csi) { case UTF_16: return SimpleWcharCodec.UTF_16; case UTF_8: return new Utf8Codec(); - + case ISO_LATIN_1: return SimpleCharCodec.ISO_LATIN_1; + default: return LatinCodec.getLatinCodec(csi); // throws if unknown } - throw new UnsupportedCharsetException("Charset registry id = " + id); } String name(); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java index dbd4a9cde..423d93b91 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java @@ -17,13 +17,14 @@ */ package org.apache.yoko.orb.CORBA; +import org.apache.yoko.codecs.CharCodec; +import org.apache.yoko.codecs.CharCodec.CharReader; +import org.apache.yoko.codecs.WcharCodec; import org.apache.yoko.io.AlignmentBoundary; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.orb.OB.CodeBaseProxy; -import org.apache.yoko.orb.OB.CodeConverterBase; import org.apache.yoko.orb.OB.CodeConverters; -import org.apache.yoko.orb.OB.CodeSetReader; import org.apache.yoko.orb.OB.ORBInstance; import org.apache.yoko.orb.OB.ObjectFactory; import org.apache.yoko.orb.OB.TypeCodeCache; @@ -54,9 +55,9 @@ import java.util.Hashtable; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.IntStream; import static java.security.AccessController.doPrivileged; +import static java.util.stream.IntStream.range; import static org.apache.yoko.io.AlignmentBoundary.EIGHT_BYTE_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.FOUR_BYTE_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.TWO_BYTE_BOUNDARY; @@ -96,7 +97,6 @@ import static org.apache.yoko.util.MinorCodes.MinorReadShortArrayOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadShortOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadStringNoTerminator; -import static org.apache.yoko.util.MinorCodes.MinorReadStringNullChar; import static org.apache.yoko.util.MinorCodes.MinorReadStringOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadStringZeroLength; import static org.apache.yoko.util.MinorCodes.MinorReadULongArrayOverflow; @@ -171,19 +171,8 @@ final public class YokoInputStream extends InputStreamWithOffsets { private TypeCodeCache cache_; - // - // Character conversion properties - // private CodeConverters codeConverters_; - private boolean charReaderRequired_; - - private boolean charConversionRequired_; - - private boolean wCharReaderRequired_; - - private boolean wCharConversionRequired_; - private CodeBase sendingContextRuntime_; private String codebase_; @@ -592,7 +581,7 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool String id = read_string(); if (logger.isLoggable(Level.FINE)) - logger.fine(String.format("Abstract interface typecode encapsulaton length=0x%x id=%s", length, id)); + logger.fine(String.format("Abstract interface typecode encapsulation length=0x%x id=%s", length, id)); if (isTopLevel && cache_ != null) tc = checkCache(id, typePos, length); // may advance pos @@ -704,109 +693,27 @@ private static boolean toBoolean(byte b) { public char read_char() { checkChunk(); - if (readBuffer.available() < 1) throw newMarshalError(MinorReadCharOverflow); - - if (charReaderRequired_ || charConversionRequired_) { - final CodeConverterBase converter = codeConverters_.inputCharConverter; - - if (charReaderRequired_ && charConversionRequired_) - return converter.convert(converter.read_char(readBuffer)); - else if (charReaderRequired_) - return converter.read_char(readBuffer); - else - return converter.convert(readBuffer.readByteAsChar()); - } else { - return readBuffer.readByteAsChar(); + try { + return codeConverters_.charCodec.readChar(readBuffer); + } catch (IndexOutOfBoundsException e) { + throw newMarshalError(MinorReadCharOverflow, e); } } public char read_wchar() { - return read_wchar(false); - } - - private char read_wchar(boolean partOfString) { checkChunk(); - - char value; - final CodeConverterBase converter = codeConverters_.inputWcharConverter; - - if (wCharReaderRequired_) { - if (!partOfString) converter.set_reader_flags(CodeSetReader.FIRST_CHAR); - - int wcLen = 2; - + try { switch (giopVersion_) { case GIOP1_0: - // we should not require a reader for GIOP 1.0 - // wchars since this would mean we are using UTF-16. - // This is not available in Orbix/E compatibility, - // only UCS-2... - throw Assert.fail(); - case GIOP1_1: readBuffer.align(TWO_BYTE_BOUNDARY); - break; - - default : - wcLen = readBuffer.readByteAsChar(); - break; - } - - if (readBuffer.available() < wcLen) throw newMarshalError(MinorReadWCharOverflow); - - // - // read in the value with the reader - // - value = converter.read_wchar(readBuffer, wcLen); - } else { - // - // no reader is required then - // - switch (giopVersion_) { - case GIOP1_0: - // UCS-2 is the native wchar codeset for both Orbacus and Orbix/E so conversion should not be necessary - Assert.ensure(!wCharConversionRequired_); - - readBuffer.align(TWO_BYTE_BOUNDARY); - - // assume big-endian (both Orbacus and Orbix/E do here) and read in the wchar - try { - return readBuffer.readChar(); - } catch (IndexOutOfBoundsException e) { - throw newMarshalError(MinorReadWCharOverflow, e); - } - - case GIOP1_1: // TODO: understand or safely delete this case - // read according to the endian of the message - if (converter.getSourceCodeSet().max_bytes <= 2) - value = (char) read_ushort(); - else - value = (char) read_ulong(); - break; - - default : { - // read the length octet off the front - final int wcLen = readBuffer.readByteAsChar(); - - // read the character off in proper endian format - try { - value = swap_ ? readBuffer.readChar_LE() : readBuffer.readChar(); - } catch (IndexOutOfBoundsException e) { - throw newMarshalError(MinorReadWCharOverflow, e); - } - - break; - } + return codeConverters_.wcharCodec.readCharWithEndianFlag(readBuffer, swap_); + default: + return codeConverters_.wcharCodec.readLengthAndChar(readBuffer); } + } catch (IndexOutOfBoundsException e) { + throw newMarshalError(MinorReadWCharOverflow, e); } - - // - // perform conversion is necessary - // - if (wCharConversionRequired_) - value = converter.convert(value); - - return value; } public byte read_octet() { @@ -905,131 +812,81 @@ public String read_string() { // Java strings don't need null terminators, so our string length will be at most one less than the byte count StringBuilder sb = new StringBuilder(byteCount - 1); - final CodeConverterBase converter = codeConverters_.inputCharConverter; - final int expectedRemainder = readBuffer.available() - (byteCount - 1); - - while (readBuffer.available() > expectedRemainder) { - final char value = charReaderRequired_ ? converter.read_char(readBuffer) : readBuffer.readByteAsChar(); + final CharCodec codec = codeConverters_.charCodec; + final int endPosition = readBuffer.getPosition() + byteCount - 1; - // String must not contain null characters - if (value == 0) throw newMarshalError(MinorReadStringNullChar); - - sb.append(charConversionRequired_ ? converter.convert(value) : value); + try { + while (readBuffer.getPosition() < endPosition) { + sb.append(codec.readChar(readBuffer)); + } + } catch (IndexOutOfBoundsException e) { + throw newMarshalError(MinorReadStringOverflow, e); } - // throw MARSHAL if the converter read too many bytes - if (readBuffer.available() < expectedRemainder) throw newMarshalError(MinorReadStringOverflow); - + // throw MARSHAL if the converter read too many bytes + if (readBuffer.getPosition() > endPosition) throw newMarshalError(MinorReadStringOverflow); + // All the supported char codecs would use a single zero byte for a null character. + // The COLLOCATED codec writes two-byte Java chars (even for non-wide char encoding) + // but this is only ever to the same ORB, so it is ok to read a single zero byte + // as long as this is written explicitly in write_string() as well as here. + // (i.e. do NOT use the codec to write the null terminator) if (readBuffer.readByte() != 0) throw newMarshalError(MinorReadStringNoTerminator); return sb.toString(); } public String read_wstring() { - final String s; checkChunk(); - - final CodeConverterBase converter = codeConverters_.inputWcharConverter; - - // - // read the length of the string (specified in characters for - // GIOP 1.0/1.1 and in octets for GIOP 1.2+) - // - int len = read_ulong(); - if (logger.isLoggable(Level.FINE)) - logger.fine(String.format("Reading wstring of length 0x%x", len)); - - switch (giopVersion_) { - - case GIOP1_0: - case GIOP1_1: { - // - // it is not legal in GIOP 1.0/1.1 for a string to be 0 in - // length... it MUST have a null terminator - // - if (len == 0) { - throw newMarshalError(MinorReadWStringZeroLength); - } - - char[] tmp = new char[len]; - - if (wCharReaderRequired_) { - converter.set_reader_flags(CodeSetReader.FIRST_CHAR); - } - - for (int i = 0; i < len; i++) { - tmp[i] = read_wchar(true); - } - - // - // Check for terminating null wchar - // - if (tmp[len - 1] != 0) - throw newMarshalError(MinorReadWStringNoTerminator); - - // - // create the final string - // - s = new String(tmp, 0, len - 1); - - break; + try { + switch (giopVersion_) { + case GIOP1_0: + case GIOP1_1: + return read_wstring_pre_1_2(); + default: + return read_wstring_1_2(); } + } catch (IndexOutOfBoundsException e) { + throw newMarshalError(MinorReadWStringOverflow, e); + } + } - default : { - StringBuilder stringBuffer = new StringBuilder(len); + private String read_wstring_pre_1_2() { + // read the length of the string (in characters for GIOP 1.0/1.1) + int numChars = read_ulong(); + if (logger.isLoggable(Level.FINE)) logger.fine(String.format("Reading GIOP 1.0 wstring of length %d chars", numChars)); + // it is not legal in GIOP 1.0/1.1 for a string to be 0 in length... it MUST have a null terminator + if (numChars == 0) throw newMarshalError(MinorReadWStringZeroLength); + // in GIOP 1.0/1.1, every char must be encoded as EXACTLY two bytes + if (readBuffer.available() < numChars * 2) throw newMarshalError(MinorReadWStringOverflow); - if (wCharReaderRequired_) { - converter.set_reader_flags(CodeSetReader.FIRST_CHAR); + // in GIOP 1.0/1.1, there is no BOM - use the endianness from context + char[] tmp = new char[numChars]; - // - // start adding the characters to the string buffer - // - while (len > 0) { - if (readBuffer.available() < 2) - throw newMarshalError(MinorReadWStringOverflow); + final WcharCodec wcharCodec = codeConverters_.wcharCodec; + for (int i = 0; i < numChars; i++) tmp[i] = wcharCodec.readCharWithEndianFlag(readBuffer, swap_); - int wcLen = converter.read_count_wchar(readBuffer.peekChar()); + // Check for terminating null wchar + if (0 != tmp[numChars - 1]) throw newMarshalError(MinorReadWStringNoTerminator); - len -= wcLen; + return new String(tmp, 0, numChars - 1); + } - // check for an overflow in the read - if (readBuffer.available() < wcLen) throw newMarshalError(MinorReadWStringOverflow); + private String read_wstring_1_2() { + // read the length of the string (in octets for GIOP 1.2+) + int numOctets = read_ulong(); + if (readBuffer.available() < numOctets) throw newMarshalError(MinorReadWStringOverflow); - char c = converter.read_wchar(readBuffer, wcLen); - if (wCharConversionRequired_) c = converter.convert(c); - // - stringBuffer.append(c); - } - } else { - final int wcLen = 2; - - while (len > 0) { - len -= wcLen; - - // read in the char using the message endian - // format for GIOP 1.2/1.3 - // REVISIT: GIOP 1.4 changes these rules - // TODO: UTF-16 never took the endianness from the message! - char c; - try { - c = swap_ ? readBuffer.readChar_LE() : readBuffer.readChar(); - } catch (IndexOutOfBoundsException e) { - throw newMarshalError((MinorReadWStringOverflow), e); - } - if (wCharConversionRequired_) - c = converter.convert(c); + if (logger.isLoggable(Level.FINE)) logger.fine(String.format("Reading GIOP 1.2 wstring of length 0x%x octets", numOctets)); + // In GIOP 1.2 there is no terminating null char, but there might be a BOM + StringBuilder builder = new StringBuilder(numOctets / 2); - stringBuffer.append(c); - } - } + final int endPosition = readBuffer.getPosition() + numOctets; + // this method checks for and consumes a BOM if present, returning the appropriately endian char reader + CharReader reader = codeConverters_.wcharCodec.beginToReadString(readBuffer); - s = stringBuffer.toString(); + while (readBuffer.getPosition() < endPosition) builder.append(reader.readChar(readBuffer)); - break; - } - } - - return s; + return builder.toString(); } public void read_boolean_array(boolean[] value, int offset, int length) { @@ -1040,42 +897,11 @@ public void read_boolean_array(boolean[] value, int offset, int length) { } public void read_char_array(char[] value, int offset, int length) { - if (length <= 0) return; - checkChunk(); - - if (readBuffer.available() < length) throw newMarshalError(MinorReadCharArrayOverflow); - - if (!(charReaderRequired_ || charConversionRequired_)) { - for (int i = offset; i < offset + length; i++) - value[i] = readBuffer.readByteAsChar(); - } else { - final CodeConverterBase converter = codeConverters_.inputCharConverter; - - // - // Intermediate variable used for efficiency - // - boolean bothRequired = charReaderRequired_ && charConversionRequired_; - - for (int i = offset; i < offset + length; i++) { - if (bothRequired) - value[i] = converter.convert(converter.read_char(readBuffer)); - else if (charReaderRequired_) - value[i] = converter.read_char(readBuffer); - else { - final char c = readBuffer.readByteAsChar(); - value[i] = converter.convert(c); - } - } - } + for (int i = offset; i < offset + length; i++) value[i] = read_char(); } - public void read_wchar_array(char[] value, int offset, int length) { - if (length <= 0) return; - if (readBuffer.available() < length) - throw newMarshalError(MinorReadCharArrayOverflow); - - for (int i = offset; i < offset + length; i++) - value[i] = read_wchar(false); + public void read_wchar_array(char[] value, int offset, int numChars) { + for (int i = offset; i < offset + numChars; i++) value[i] = read_wchar(); } public void read_octet_array(byte[] value, int offset, int length) { @@ -1094,7 +920,7 @@ public void read_short_array(short[] value, int offset, int length) { readBuffer.align(TWO_BYTE_BOUNDARY); if (readBuffer.available() < length * 2) throw newMarshalError(MinorReadShortArrayOverflow); - IntStream.range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach(swap_ ? i -> value[i] = readBuffer.readShort_LE() : i -> value[i] = readBuffer.readShort()); } @@ -1115,7 +941,7 @@ public void read_long_array(int[] value, int offset, int length) { if (readBuffer.available() < length * 4) throw newMarshalError(MinorReadLongArrayOverflow); - IntStream.range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swap_ ? i -> value[i] = readBuffer.readInt_LE() : i -> value[i] = readBuffer.readInt()); } @@ -1141,7 +967,7 @@ public void read_longlong_array(long[] value, int offset, int length) { checkChunk(); readBuffer.align(EIGHT_BYTE_BOUNDARY); if (readBuffer.available() < length * 8) throw newMarshalError(MinorReadLongLongArrayOverflow); - IntStream.range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swap_ ? i -> value[i] = readBuffer.readLong_LE() : i -> value[i] = readBuffer.readLong()); } @@ -1159,7 +985,7 @@ public void read_float_array(float[] value, int offset, int length) { checkChunk(); readBuffer.align(FOUR_BYTE_BOUNDARY); if (readBuffer.available() < length * 4) throw newMarshalError(MinorReadFloatArrayOverflow); - IntStream.range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swap_ ? i -> value[i] = readBuffer.readFloat_LE() : i -> value[i] = readBuffer.readFloat()); } @@ -1169,7 +995,7 @@ public void read_double_array(double[] value, int offset, int length) { checkChunk(); readBuffer.align(EIGHT_BYTE_BOUNDARY); if (readBuffer.available() < length * 8) throw newMarshalError(MinorReadDoubleArrayOverflow); - IntStream.range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swap_ ? i -> value[i] = readBuffer.readDouble_LE() : i -> value[i] = readBuffer.readDouble()); } @@ -1267,7 +1093,7 @@ private Class getRMIStubClass(Strin public TypeCode read_TypeCode() { // NOTE: // No data with natural alignment of greater than four octets - // is needed for TypeCode. Therefore it is not necessary to do + // is needed for TypeCode. Therefore, it is not necessary to do // encapsulation in a separate buffer. checkChunk(); return readTypeCodeImpl(new Hashtable<>(), true); @@ -1364,10 +1190,6 @@ public Object read_abstract_interface(@SuppressWarnings("rawtypes") Class clz) { return valueReader().readAbstractInterface(clz); } - // ------------------------------------------------------------------ - // ORBacus-specific methods - // ------------------------------------------------------------------ - public void read_value(org.omg.CORBA.Any any, TypeCode tc) { valueReader().readValueAny(any, tc); } @@ -1415,24 +1237,7 @@ public YokoInputStream(byte[] data) { public void _OB_codeConverters(CodeConverters converters, GiopVersion giopVersion) { if (giopVersion != null) giopVersion_ = giopVersion; - charReaderRequired_ = false; - charConversionRequired_ = false; - wCharReaderRequired_ = false; - wCharConversionRequired_ = false; - codeConverters_ = CodeConverters.createCopy(converters); - - if (converters != null) { - if (codeConverters_.inputCharConverter != null) { - charReaderRequired_ = codeConverters_.inputCharConverter.readerRequired(); - charConversionRequired_ = codeConverters_.inputCharConverter.conversionRequired(); - } - - if (codeConverters_.inputWcharConverter != null) { - wCharReaderRequired_ = codeConverters_.inputWcharConverter.readerRequired(); - wCharConversionRequired_ = codeConverters_.inputWcharConverter.conversionRequired(); - } - } } public CodeConverters _OB_codeConverters() { diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java index 7131011dd..406e242ea 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java @@ -17,12 +17,13 @@ */ package org.apache.yoko.orb.CORBA; +import org.apache.yoko.codecs.CharCodec; +import org.apache.yoko.codecs.WcharCodec; import org.apache.yoko.io.AlignmentBoundary; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.SimplyCloseable; import org.apache.yoko.io.WriteBuffer; -import org.apache.yoko.orb.OB.CodeConverterBase; import org.apache.yoko.orb.OB.CodeConverters; import org.apache.yoko.orb.OB.ORBInstance; import org.apache.yoko.orb.OB.TypeCodeFactory; @@ -31,7 +32,6 @@ import org.apache.yoko.util.Assert; import org.apache.yoko.util.Timeout; import org.omg.CORBA.BAD_TYPECODE; -import org.omg.CORBA.DATA_CONVERSION; import org.omg.CORBA.LocalObject; import org.omg.CORBA.MARSHAL; import org.omg.CORBA.NO_IMPLEMENT; @@ -53,10 +53,10 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import java.util.Vector; import java.util.logging.Logger; +import static java.util.logging.Level.FINEST; import static org.apache.yoko.io.AlignmentBoundary.EIGHT_BYTE_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.FOUR_BYTE_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.NO_BOUNDARY; @@ -113,11 +113,6 @@ public final class YokoOutputStream extends OutputStream implements ValueOutputS private final WriteBuffer writeBuffer; private final GiopVersion giopVersion_; private final CodeConverters codeConverters_; - private final boolean charWriterRequired_; - private final boolean charConversionRequired_; - private final boolean wCharWriterRequired_; - private final boolean wCharConversionRequired_; - private final boolean charBoundsCheckRequired_; // Handles all OBV marshalling private ValueWriter valueWriter_; @@ -137,11 +132,8 @@ private SimplyCloseable recordLength() { } private void writeTypeCodeImpl(TypeCode tc, Map history) { - // // Try casting the TypeCode to org.apache.yoko.orb.CORBA.TypeCode. This - // could - // fail if the TypeCode was created by a foreign singleton ORB. - // + // could fail if the TypeCode was created by a foreign singleton ORB. TypeCodeImpl obTC = null; try { obTC = (TypeCodeImpl) tc; @@ -157,7 +149,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { } } - LOGGER.finest("Writing a type code of type " + tc.kind().value()); + if (LOGGER.isLoggable(FINEST)) LOGGER.finest("Writing a type code of type " + (tc == null ? null : tc.kind())); // For performance reasons, handle the primitive TypeCodes first switch (tc.kind().value()) { @@ -210,7 +202,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { case _tk_native: { history.put(tc, oldPos); - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); write_string(tc.id()); write_string(tc.name()); @@ -223,7 +215,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { case _tk_except: { history.put(tc, oldPos); - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); write_string(tc.id()); write_string(tc.name()); @@ -240,7 +232,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { case _tk_union: { history.put(tc, oldPos); - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); write_string(tc.id()); write_string(tc.name()); @@ -303,7 +295,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { case _tk_enum: { history.put(tc, oldPos); - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); write_string(tc.id()); write_string(tc.name()); @@ -324,7 +316,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { case _tk_array: { history.put(tc, oldPos); - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); writeTypeCodeImpl(tc.content_type(), history); write_ulong(tc.length()); @@ -337,7 +329,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { case _tk_value_box: { history.put(tc, oldPos); - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); write_string(tc.id()); write_string(tc.name()); @@ -355,7 +347,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { concreteBase = TypeCodeFactory.createPrimitiveTC(tk_null); } - try (SimplyCloseable sc = recordLength()) { + try (SimplyCloseable ignored = recordLength()) { _OB_writeEndian(); write_string(tc.id()); write_string(tc.name()); @@ -444,108 +436,28 @@ public void write_boolean(boolean value) { } public void write_char(char value) { - if (value > 255) - throw new DATA_CONVERSION("char value exceeds 255: " + (int) value); - - addCapacity(1); - - final CodeConverterBase converter = codeConverters_.outputCharConverter; - - if (charConversionRequired_) - value = converter.convert(value); - - if (charWriterRequired_) - converter.write_char(writeBuffer, value); - else - writeBuffer.writeByte(value); + final CharCodec codec = codeConverters_.charCodec; + addCapacity(codec.octetCount(value)); + codec.writeChar(value, writeBuffer); } public void write_wchar(char value) { - write_wchar(value, false); - } - - private void write_wchar(char value, boolean partOfString) { - final CodeConverterBase converter = codeConverters_.outputWcharConverter; - - // - // pre-convert the character if necessary - // - if (wCharConversionRequired_) - value = converter.convert(value); - - if (wCharWriterRequired_) { - // - // For GIOP 1.1 non byte-oriented wide characters are written - // as ushort or ulong, depending on their maximum length - // listed in the code set registry. - // - switch (giopVersion_) { - case GIOP1_0: - // we don't support special writers for GIOP 1.0 if - // conversion is required or if a writer is required - throw Assert.fail(); - - case GIOP1_1: { - // get the length of the character - int len = converter.write_count_wchar(value); - - // For GIOP 1.1 we are limited to 2-byte wchars - // so make sure to check for that - Assert.ensure(len == 2); - - // allocate aligned space - addCapacity(2, TWO_BYTE_BOUNDARY); - - // write using the writer - converter.write_wchar(writeBuffer, value); - break; - } - - default: { - // get the length of the character - int len = converter.write_count_wchar(value); - - // write the octet length at the beginning - write_octet((byte) len); - - // add unaligned capacity - addCapacity(len); + final WcharCodec codec = codeConverters_.wcharCodec; - // write the actual character - converter.write_wchar(writeBuffer, value); - break; - } - } - } else { - switch (giopVersion_) { - case GIOP1_0: { - // Orbix2000/Orbacus/E compatible 1.0 marshal - - // add aligned capacity - addCapacity(2, TWO_BYTE_BOUNDARY); - - // write 2-byte character in big endian - writeBuffer.writeChar(value); - } - break; - - case GIOP1_1: { - write_ushort((short) value); - } - break; - - default: { - // add unaligned space for character - addCapacity(3); - - // write the octet length at the start - writeBuffer.writeByte(2); + switch (giopVersion_) { + case GIOP1_0: + case GIOP1_1: + // add aligned space for 1 character + addCapacity(codec.charSize(), TWO_BYTE_BOUNDARY); + // write 2-byte character in big endian + codec.writeChar(value, writeBuffer); + break; - // write the character in big endian format - writeBuffer.writeChar(value); - } - break; - } + default: + // add unaligned space for 1 length-and-character + addCapacity(codec.octetCountLengthsAndWchars(1)); + codec.writeLengthAndChar(value, writeBuffer); + break; } } @@ -587,140 +499,76 @@ public void write_double(double value) { public void write_string(String value) { LOGGER.finest("Writing string value " + value); + final CharCodec codec = codeConverters_.charCodec; final char[] arr = value.toCharArray(); - final CodeConverterBase converter = codeConverters_.outputCharConverter; - - if (charWriterRequired_) { // write one or more bytes per char - // We don't know how much space each character will require: each char could take up to four bytes. - // To avoid re-allocation, create a large enough temporary buffer up front. - // NOTE: we need to use a temporary buffer to count the bytes reliably, because - // chunking can add bytes other than just the chars to be written. - final WriteBuffer tmpWriter = Buffer.createWriteBuffer(4 + value.length() * 4 + 1); - if (charConversionRequired_) { - for (char c : arr) converter.write_char(tmpWriter, converter.convert(checkChar(c))); - } else { - for (char c : arr) converter.write_char(tmpWriter, checkChar(c)); - } - // write the null terminator - tmpWriter.writeByte(0); - // ignore any unused space in the buffer - tmpWriter.trim(); + + if (codec.isFixedWidth()) { + int numOctets = arr.length * codec.charSize() + 1; + write_ulong(numOctets); // writes the length + addCapacity(numOctets); + for (char c: arr) codec.writeChar(c, writeBuffer); + // write null terminator + writeBuffer.writeByte(0); + } else { + // UTF-8 is the only supported non-fixed-width char encoding. + // Each Java char can require at most 3 bytes of UTF-8; + // any 4 byte UTF-8 sequence is a surrogate pair in Java. + // Use a temporary buffer to count bytes needed and allocate them up front. + // This keeps the data in a single chunk (not mandatory, but sensible). + final WriteBuffer tmpWriter = Buffer.createWriteBuffer(arr.length * 3 + 1); + for (char c : arr) codec.writeChar(c, tmpWriter); + // write the null terminator and compute the length, ignoring any unused space in the buffer + int numOctets = tmpWriter.writeByte(0).trim().length(); // write the length - write_ulong(tmpWriter.length()); + write_ulong(numOctets); // and write the contents - addCapacity(tmpWriter.length()); + addCapacity(numOctets); tmpWriter.readFromStart().readBytes(writeBuffer); - } else { // write one byte per char - int len = arr.length; - int capacity = len + 1; - write_ulong(capacity); // writes the length and ensures a two-byte boundary alignment - addCapacity(capacity); - if (charConversionRequired_) { - for (char c: arr) writeBuffer.writeByte(converter.convert(checkChar(c))); - } else { - for (char c: arr) writeBuffer.writeByte(checkChar(c)); - } - // write null terminator - writeBuffer.writeByte(0); } } - private char checkChar(char c) { - // Only validate for 8-bit charsets (not UTF-8, UTF-16, or UCS-2) - if (charBoundsCheckRequired_ && c > 0xff) { - throw new DATA_CONVERSION( - String.format("Character 0x%04x out of range for 8-bit charset", (int)c)); - } - return c; - } - public void write_wstring(String value) { - final char[] arr = value.toCharArray(); - final int len = arr.length; - - LOGGER.finest("Writing wstring value " + value); - // - // get converter/writer instance - // - final CodeConverterBase converter = codeConverters_.outputWcharConverter; - - // - // for GIOP 1.0/1.1 we don't need to differentiate between - // strings requiring a writer/converter (or not) since they can - // be handled by the write_wchar() method - // + if (LOGGER.isLoggable(FINEST)) LOGGER.finest("Writing wstring value " + value); switch (giopVersion_) { case GIOP1_0: case GIOP1_1: - // - // write the length of the string - // - write_ulong(len + 1); - - // - // now write all the characters - // - for (char anArr : arr) write_wchar(anArr, true); - - // - // and the null terminator - // - write_wchar((char) 0, true); - return; + write_wstring_pre_1_2(value); + break; default: + write_wstring_1_2(value); } + } - // save the starting position and write the gap to place the length of the string later - try (SimplyCloseable sc = recordLength()) { - if (wCharWriterRequired_) { - for (char anArr : arr) { - char v = anArr; - - // - // check if the character requires conversion - // - if (wCharConversionRequired_) v = converter.convert(v); - - // - // add capacity for the character - // - addCapacity(converter.write_count_wchar(v)); - - // - // write the character - // - converter.write_wchar(writeBuffer, v); - } - } else { - // - // since we don't require a special writer, each character - // MUST be 2-bytes in size - // - addCapacity(len << 1); - - for (char anArr : arr) { - char v = anArr; - - // - // check for conversion - // - if (wCharConversionRequired_) v = converter.convert(v); - - // - // write character in big endian format - // - writeBuffer.writeChar(v); - } - } - } - - // - // we've handled GIOP 1.0/1.1 above so this must be GIOP 1.2+ - // + private void write_wstring_pre_1_2(String value) { + // write the length of the string in chars + write_ulong(value.length() + 1); + // already 4-byte aligned, so just add the needed capacity for len 2-byte chars + addCapacity(2*(value.length() + 1)); + final WcharCodec codec = codeConverters_.wcharCodec; + // now write all the characters + for (int i = 0; i < value.length(); i++) codec.writeChar(value.charAt(i), writeBuffer); + // and the null terminator + codec.writeChar((char) 0, writeBuffer); + } - // - // write the octet length - // + private void write_wstring_1_2(String value) { + // GIOP 1.2 encodes the length of the string in octets and does not require a null terminator + // first deal with the empty string case + if (value.isEmpty()) { + write_ulong(0); + return; + } + // now we know there is a first character + final WcharCodec codec = codeConverters_.wcharCodec; + int numOctets = codec.octetCount(value); + // write the length of the string in octets + write_ulong(numOctets); + // add unaligned capacity + addCapacity(numOctets); + // write the first character, including optional BOM + codec.beginToWriteString(value.charAt(0), writeBuffer); + // write the rest of the characters + for (int i = 1; i < value.length(); i++) codec.writeChar(value.charAt(i), writeBuffer); } public void write_boolean_array(boolean[] value, int offset, int length) { @@ -733,43 +581,11 @@ public void write_boolean_array(boolean[] value, int offset, int length) { } public void write_char_array(char[] value, int offset, int length) { - if (length > 0) { - addCapacity(length); - - if (!(charWriterRequired_ || charConversionRequired_)) { - for (int i = offset; i < offset + length; i++) { - if (value[i] > 255) - throw new DATA_CONVERSION("char value exceeds 255: " + (int) value[i]); - - writeBuffer.writeByte(value[i]); - } - } else { - final CodeConverterBase converter = codeConverters_.outputCharConverter; - - // - // Intermediate variable used for efficiency - // - boolean bothRequired = charWriterRequired_ - && charConversionRequired_; - - for (int i = offset; i < offset + length; i++) { - if (value[i] > 255) - throw new DATA_CONVERSION("char value exceeds 255: " + (int) value[i]); - - if (bothRequired) - converter.write_char(writeBuffer, converter.convert(value[i])); - else if (charWriterRequired_) - converter.write_char(writeBuffer, value[i]); - else - writeBuffer.writeByte(converter.convert(value[i])); - } - } - } + for (int i = offset; i < offset + length; i++) write_char(value[i]); } public void write_wchar_array(char[] value, int offset, int length) { - for (int i = offset; i < offset + length; i++) - write_wchar(value[i], false); + for (int i = offset; i < offset + length; i++) write_wchar(value[i]); } public void write_octet_array(byte[] value, int offset, int length) { @@ -864,7 +680,7 @@ public void write_Object(org.omg.CORBA.Object value) { public void write_TypeCode(TypeCode t) { // NOTE: // No data with natural alignment of greater than four octets - // is needed for TypeCode. Therefore it is not necessary to do + // is needed for TypeCode. Therefore, it is not necessary to do // encapsulation in a separate buffer. if (t == null) throw new BAD_TYPECODE("TypeCode is nil"); @@ -1157,13 +973,9 @@ private void copyArrayFrom(org.omg.CORBA.portable.InputStream in, TypeCode tc) t break; case _tk_char: - if (charWriterRequired_ || charConversionRequired_) { - char[] ch = new char[len]; - in.read_char_array(ch, 0, len); - write_char_array(ch, 0, len); - } else { - readFrom(in, len); - } + char[] ch = new char[len]; + in.read_char_array(ch, 0, len); + write_char_array(ch, 0, len); break; case _tk_wchar: { @@ -1489,28 +1301,6 @@ public YokoOutputStream(WriteBuffer writeBuffer) { public YokoOutputStream(WriteBuffer writeBuffer, CodeConverters converters, GiopVersion giopVersion) { this.writeBuffer = writeBuffer; this.giopVersion_ = giopVersion == null ? GIOP1_0 : giopVersion; - - { - Optional charConv = Optional.ofNullable(converters).map(c -> c.outputCharConverter); - this.charWriterRequired_ = charConv.map(cc -> cc.writerRequired()).orElse(false); - this.charConversionRequired_ = charConv.map(cc -> cc.conversionRequired()).orElse(false); - // Cache whether bounds checking is needed for char conversion - // UTF-8, UTF-16, and UCS-2 can handle full 16-bit range, others need validation - this.charBoundsCheckRequired_ = charConv - .map(cc -> { - org.apache.yoko.orb.OB.CodeSetInfo destCodeSet = cc.getDestinationCodeSet(); - return destCodeSet != org.apache.yoko.orb.OB.CodeSetInfo.UTF_8 - && destCodeSet != org.apache.yoko.orb.OB.CodeSetInfo.UTF_16 - && destCodeSet != org.apache.yoko.orb.OB.CodeSetInfo.UCS_2; - }) - .orElse(Boolean.FALSE); - } - { - Optional wcharConv = Optional.ofNullable(converters).map(c -> c.outputWcharConverter); - this.wCharWriterRequired_ = wcharConv.map(cc -> cc.writerRequired()).orElse(false); - this.wCharConversionRequired_ = wcharConv.map(cc -> cc.conversionRequired()).orElse(false); - } - this.codeConverters_ = CodeConverters.createCopy(converters); } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterBase.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterBase.java deleted file mode 100644 index 0342ccc59..000000000 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterBase.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2025 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -import org.apache.yoko.io.ReadBuffer; -import org.apache.yoko.io.WriteBuffer; -import org.apache.yoko.util.Assert; -import org.omg.CORBA.DATA_CONVERSION; - -import java.util.Objects; - -import static org.apache.yoko.orb.OB.CodeSetInfo.UTF_16; -import static org.apache.yoko.orb.OB.CodeSetInfo.UTF_8; - -abstract public class CodeConverterBase { - private final CodeSetInfo sourceCodeSet; - - private final CodeSetInfo destinationCodeSet; - - // - // The UTF-8 or fixed width reader/writer - // - private final CodeSetReader reader_; - - private final CodeSetWriter writer_; - - CodeConverterBase(CodeSetInfo source, CodeSetInfo destination) { - if (source == null) - source = CodeSetInfo.NONE; - if (destination == null) - destination = CodeSetInfo.NONE; - - sourceCodeSet = source; - destinationCodeSet = destination; - - if (source == UTF_8) - reader_ = new UTF8Reader(); - else if (source == UTF_16) - reader_ = new UTF16Reader(); - else if (source.max_bytes <= 2) - reader_ = new FixedWidth2Reader(); - else { - throw Assert.fail("Yoko doesn't support wide characters larger than 16 bit"); - } - - if (destination == UTF_8) - writer_ = new UTF8Writer(); - else if (destination == UTF_16) - writer_ = new UTF16Writer(); - else if (destination.max_bytes <= 2) - writer_ = new FixedWidth2Writer(); - else { - throw Assert.fail("Yoko doesn't support wide characters larger than 16 bit"); - } - } - - @Override - public final boolean equals(Object other) { - if (other == this) return true; - return (other instanceof CodeConverterBase) && this.equals((CodeConverterBase) other); - } - - private boolean equals(CodeConverterBase that) { - return this.sourceCodeSet == that.sourceCodeSet && this.destinationCodeSet == that.destinationCodeSet; - } - - @Override - public int hashCode() { - return Objects.hash(sourceCodeSet, destinationCodeSet); - } - - public final char read_char(ReadBuffer readBuffer) throws DATA_CONVERSION { - return reader_.read_char(readBuffer); - } - - public char read_wchar(ReadBuffer readBuffer, int len) throws DATA_CONVERSION { - return reader_.read_wchar(readBuffer, len); - } - - public void write_char(WriteBuffer writeBuffer, char v) throws DATA_CONVERSION { - writer_.write_char(writeBuffer, v); - } - - public void write_wchar(WriteBuffer writeBuffer, char v) throws DATA_CONVERSION { - writer_.write_wchar(writeBuffer, v); - } - - public int read_count_wchar(char v) { - return reader_.count_wchar(v); - } - - public int write_count_wchar(char v) { - return writer_.count_wchar(v); - } - - final public boolean readerRequired() { - return (sourceCodeSet == UTF_8) || (sourceCodeSet == UTF_16); - } - - final public boolean writerRequired() { - return (destinationCodeSet == UTF_8) || (destinationCodeSet == UTF_16); - } - - final public CodeSetInfo getSourceCodeSet() { - return sourceCodeSet; - } - - final public CodeSetInfo getDestinationCodeSet() { - return destinationCodeSet; - } - - final public void set_reader_flags(int flags) { - reader_.set_flags(flags); - } - - public abstract boolean conversionRequired(); - - public abstract char convert(char value); - - @Override - public String toString() { - return "CodeConverter[" + sourceCodeSet + " -> " + destinationCodeSet + ']'; - } -} diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterImpl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterImpl.java deleted file mode 100644 index 3dfeba975..000000000 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2025 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -import java.util.Objects; - -import static org.apache.yoko.orb.OB.CharMapInfo.CM_IDENTITY; - -final class CodeConverterImpl extends CodeConverterBase { - private final CharMapInfo fromMap; - private final CharMapInfo toMap; - private final boolean conversionRequired; - - CodeConverterImpl(CodeSetInfo fromSet, CodeSetInfo toSet) { - super(fromSet, toSet); - fromMap = fromSet.charMap; - toMap = toSet.charMap; - Objects.requireNonNull(fromMap); - Objects.requireNonNull(toMap); - conversionRequired = (fromMap != CM_IDENTITY) || (toMap != CM_IDENTITY); - } - - public boolean conversionRequired() { - return conversionRequired; - } - - public char convert(char v) { - return convertFromJava(convertToJava(v)); - } - - private char convertFromJava(char v) { - return toMap.convertFromJava(v); - } - - private char convertToJava(char v) { - return fromMap.convertToJava(v); - } -} diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterNone.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterNone.java deleted file mode 100644 index 0bde01257..000000000 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverterNone.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2026 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -import org.apache.yoko.orb.CORBA.YokoOutputStream; -import org.apache.yoko.io.ReadBuffer; -import org.omg.CORBA.BAD_PARAM; -import org.omg.CORBA.INV_OBJREF; - -import static org.apache.yoko.util.MinorCodes.MinorNoWcharCodeSet; -import static org.apache.yoko.util.MinorCodes.MinorWcharCodeSetRequired; -import static org.apache.yoko.util.MinorCodes.describeBadParam; -import static org.apache.yoko.util.MinorCodes.describeInvObjref; -import static org.omg.CORBA.CompletionStatus.COMPLETED_NO; - -/** - * This class represents the absence of wchar codeset in an IOR or a CodeSet service context. - * It throws exceptions when an attempt is made to convert wchar information. - * The exceptions throw are as described for the client and the server in "Code Set Negotiation" - * (see CORBA 3.0.3, section 13.10.2.6). - * Note: there is an assumption that when wchars are being written, this is on the client, - * and when they are being read, this is on the server. This assumption could be wrong. - */ -final class CodeConverterNone extends CodeConverterBase { - CodeConverterNone(CodeSetInfo fromSet, CodeSetInfo toSet) { - super(fromSet, toSet); - } - - public boolean conversionRequired() { - // conversion *is* required, but it will fail - return true; - } - - public char read_wchar(ReadBuffer readBuffer, int len) { - throw new BAD_PARAM(describeBadParam(MinorNoWcharCodeSet), MinorNoWcharCodeSet, COMPLETED_NO); - } - - public void write_wchar(YokoOutputStream out, char v) { - throw new INV_OBJREF(describeInvObjref(MinorWcharCodeSetRequired), MinorWcharCodeSetRequired, COMPLETED_NO); - } - - public int read_count_wchar(char value) { - throw new BAD_PARAM(describeBadParam(MinorNoWcharCodeSet), MinorNoWcharCodeSet, COMPLETED_NO); - } - - public int write_count_wchar(char v) { - throw new INV_OBJREF(describeInvObjref(MinorWcharCodeSetRequired), MinorWcharCodeSetRequired, COMPLETED_NO); - } - - public char convert(char v) { - throw new INV_OBJREF(describeInvObjref(MinorWcharCodeSetRequired), MinorWcharCodeSetRequired, COMPLETED_NO); - } -} diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java index 8aecc864b..fb10e27c0 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,69 +17,58 @@ */ package org.apache.yoko.orb.OB; +import org.apache.yoko.codecs.CharCodec; +import org.apache.yoko.codecs.WcharCodec; + import java.util.Objects; -import static org.apache.yoko.orb.OB.CodeSetDatabase.getConverter; -import static org.apache.yoko.orb.OB.CodeSetInfo.UTF_16; +import static org.apache.yoko.codecs.CharCodec.NULL_CODEC; -final public class CodeConverters { - // This class may look immutable, but CodeConverterBase holds reader and writer objects that are stateful and mutable - public static final CodeConverters NULL_CONVERTER = new CodeConverters(null, null, null, null); +// This class may look immutable, but charCodec can contain state (while reading a surrogate pair from UTF-8) +public final class CodeConverters { + static final CodeConverters COLLOCATED = new CodeConverters(NULL_CODEC, NULL_CODEC); - public final CodeConverterBase inputCharConverter; - public final CodeConverterBase outputCharConverter; - public final CodeConverterBase inputWcharConverter; - public final CodeConverterBase outputWcharConverter; + public final CharCodec charCodec; + public final WcharCodec wcharCodec; - private CodeConverters(CodeConverterBase charIn, CodeConverterBase charOut, CodeConverterBase wcharIn, CodeConverterBase wcharOut) { - inputCharConverter = charIn; - outputCharConverter = charOut; - inputWcharConverter = wcharIn; - outputWcharConverter = wcharOut; + private CodeConverters(CharCodec cc, WcharCodec wc) { + this.charCodec = cc; + this.wcharCodec = wc; } - private CodeConverters(CodeConverters c) { - this(c.inputCharConverter, c.outputCharConverter, c.inputWcharConverter, c.outputWcharConverter); + private CodeConverters(CodeConverters that) { + this(that.charCodec.getInstanceOrCopy(), that.wcharCodec.getInstanceOrCopy()); } public static CodeConverters createCopy(CodeConverters template) { - if (template == null) return NULL_CONVERTER; - if (template == NULL_CONVERTER) return NULL_CONVERTER; + if (template == null) return COLLOCATED; + if (template == COLLOCATED) return COLLOCATED; return new CodeConverters(template); } - public static CodeConverters create(ORBInstance orbInst, int alienCs, int alienWcs) { - final int nativeCs = orbInst.getNativeCs(); - final int nativeWcs = orbInst.getNativeWcs(); - final CodeConverterBase charIn = getConverter(alienCs, nativeCs); - final CodeConverterBase charOut = getConverter(nativeCs, alienCs); - final CodeConverterBase wcharIn = getConverter(alienWcs, nativeWcs); - final CodeConverterBase wcharOut = getConverter(nativeWcs, alienWcs); - if (charIn == null && charOut == null && wcharIn == null && wcharOut == null) return NULL_CONVERTER; - return new CodeConverters(charIn, charOut, wcharIn, wcharOut); + public static CodeConverters create(int tcs, int twcs) { + CharCodec cc = CharCodec.forRegistryId(tcs); + WcharCodec wc = WcharCodec.forRegistryId(twcs); + return new CodeConverters(cc, wc); } public static CodeConverters createForWcharWriteOnly() { - return new CodeConverters(null, null, null, getConverter(UTF_16, UTF_16)); + return new CodeConverters(null, WcharCodec.getDefault()); } - public boolean equals(Object other) { - if (! (other instanceof CodeConverters)) return false; - - CodeConverters that = (CodeConverters) other; - - return Objects.equals(this.inputCharConverter, that.inputCharConverter) && - Objects.equals(this.outputCharConverter, that.outputCharConverter) && - Objects.equals(this.inputWcharConverter, that.inputWcharConverter) && - Objects.equals(this.outputWcharConverter, that.outputWcharConverter); + @Override + public boolean equals(Object o) { + if (!(o instanceof CodeConverters)) return false; + CodeConverters that = (CodeConverters) o; + return Objects.equals(charCodec, that.charCodec) && Objects.equals(wcharCodec, that.wcharCodec); } + @Override public int hashCode() { - return Objects.hash(inputCharConverter, outputCharConverter, inputWcharConverter, outputWcharConverter); + return Objects.hash(charCodec, wcharCodec); } public String toString() { - return String.format("CodeConverters{%noutputCharConverter=%s%noutputWcharConverter=%s%n}", - outputCharConverter, outputWcharConverter); + return String.format("CodeConverters{%ncharCodec=%s%nwcharCodec=%s%n}", charCodec, wcharCodec); } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetDatabase.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetDatabase.java index 8b92e4e97..6d1ff9df7 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetDatabase.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetDatabase.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,22 +27,6 @@ enum CodeSetDatabase { ; - static CodeConverterBase getConverter(int from, int to) { - CodeSetInfo fromSet = CodeSetInfo.forRegistryId(from); - CodeSetInfo toSet = CodeSetInfo.forRegistryId(to); - return getConverter(fromSet, toSet); - } - - static CodeConverterBase getConverter(CodeSetInfo fromSet, CodeSetInfo toSet) { - // Optimization: don't use converter for identical narrow codesets - if (toSet != null && toSet == fromSet && toSet.max_bytes == 1) return null; - - if (fromSet == null || toSet == null) return new CodeConverterNone(fromSet, toSet); - - // the unsupported codesets should have been filtered out by the initial handshake - return new CodeConverterImpl(fromSet, toSet); - } - /** * The logic of this method is taken from "Code Set Negotiation" (see CORBA 3.0.3 section 13.10.2.6). * Given what we know about the client (i.e. our) codeset, it could be simplified further, diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java index f77a3bb6d..d9b5cf715 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java @@ -80,13 +80,13 @@ static CodeConverters getCodeConverters(ORBInstance orbInstance, ProfileInfo pro final CodeSetComponentInfo info = getCodeSetInfoFromComponents(orbInstance, profileInfo); - if (info == null) return CodeConverters.create(orbInstance, ISO_LATIN_1.id, orbInstance.getDefaultWcs()); + if (info == null) return CodeConverters.create(ISO_LATIN_1.id, orbInstance.getDefaultWcs()); CodeSetComponent client_cs = createCodeSetComponent(orbInstance.getNativeCs(), false); CodeSetComponent client_wcs = createCodeSetComponent(orbInstance.getNativeWcs(), true); final int tcs_c = determineTCS(client_cs, info.ForCharData, UTF_8.id); final int tcs_wc = determineTCS(client_wcs, info.ForWcharData, UTF_16.id); - return CodeConverters.create(orbInstance, tcs_c, tcs_wc); + return CodeConverters.create(tcs_c, tcs_wc); } static CodeSetContext extractCodeSetContext(ServiceContext csSC) { diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java index 081c84d30..dfc9b438a 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java @@ -17,7 +17,7 @@ */ package org.apache.yoko.orb.OB; -import static org.apache.yoko.orb.OB.CodeConverters.NULL_CONVERTER; +import static org.apache.yoko.orb.OB.CodeConverters.COLLOCATED; import org.apache.yoko.orb.CORBA.YokoOutputStream; import org.apache.yoko.orb.CORBA.OutputStreamHolder; @@ -39,7 +39,7 @@ public final class CollocatedClient extends Client implements DowncallEmitter { // ---------------------------------------------------------------------- public CollocatedClient(CollocatedServer server, int concModel) { - super(concModel, NULL_CONVERTER); + super(concModel, COLLOCATED); server_ = server; } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java index 1eaf0493e..b7977725e 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java @@ -169,7 +169,7 @@ private void readCodeConverters(ServiceContexts contexts) { if (csSC == null) return; CodeSetContext csCtx = CodeSetUtil.extractCodeSetContext(csSC); - this.codeConverters_ = CodeConverters.create(orbInstance_, csCtx.char_data, csCtx.wchar_data); + this.codeConverters_ = CodeConverters.create(csCtx.char_data, csCtx.wchar_data); if (CONN_IN_LOG.isLoggable(Level.FINEST)) { String msg = String.format("receiving transmission code sets%nchar code set: %s%nwchar code set: %s", diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java index 3b1b795d8..6c8297730 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java @@ -17,8 +17,6 @@ */ package org.apache.yoko.codecs; -import org.apache.yoko.codecs.CharCodec; -import org.apache.yoko.codecs.WcharCodec; import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; From 38ca7992dc4d1e6a4a8a42a910eb1e6af5132fb3 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Wed, 4 Feb 2026 11:28:09 +0000 Subject: [PATCH 04/18] refactor(codecs): rename and simplify codec holder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete the transition from CodeConverter to CharCodec/WcharCodec by removing all legacy converter classes and updating remaining references throughout the codebase. This is the final commit in the codec refactoring series. BREAKING CHANGES: - Remove CodeConverterBase, CodeConverterImpl, CodeConverterNone classes - Remove CodeSetReader, CodeSetWriter, UTF8Reader, UTF8Writer classes - Remove CharMapInfo enum and character mapping database - Rename CodeConverters to CodecPair throughout codebase - Remove CodeSetDatabase.getConverter() method - Delete org.apache.yoko.orb.CORBA.Any class (1138 lines) - Remove ConversionWidthsTest and TestCharMapConversions test classes Core changes: - Rename CodeConverters class to CodecPair: - Replace converter fields with charCodec and wcharCodec - Rename NULL_CONVERTER to COLLOCATED - Simplify create() to use CharCodec/WcharCodec.forRegistryId() - Remove ORBInstance parameter from create() method - Update createForWcharWriteOnly() to use WcharCodec.getDefault() - Add getCodeSetInfo() method to CharCodec interface: - Implement in SimpleCharCodec (US_ASCII, ISO_LATIN_1) - Implement in SimpleWcharCodec (UTF_16, NULL) - Implement in Utf8Codec (UTF_8) - Implement in LatinCodec with CodeSetInfo field - Returns CodeSetInfo.NONE for NULL codec - Update Util class documentation and implementation: - Fix typo: "multi-byte" → "multibyte" - Improve javadoc for expect7bit(), require7bit(), require8bit() - Use bit-shift operators for clearer bounds checking - Fix comment: "unicode" → "Unicode" - Update YokoInputStream: - Rename _OB_codeConverters() to getCodecs() - Update all internal references to use codecs field - Update method calls to use CodecPair - Update YokoOutputStream: - Update constructor to use CodecPair - Update all internal references to use codecs field - Update all client code: - CollocatedClient: use CodecPair.COLLOCATED - GIOPConnection: use CodecPair.create() - CodeSetUtil: remove ORBInstance parameter from create() calls - Upcall: use getCodecs() instead of _OB_codeConverters() - UnresolvedException: use getCodecs() instead of _OB_codeConverters() - UtfStringsTest: use CodecPair instead of CodeConverters Removed legacy code: - Delete 1138-line Any.java class (replaced by modern implementation) - Delete CodeConverterBase abstract class and implementations - Delete CodeSetReader/Writer interfaces and UTF8Reader/Writer - Delete CharMapInfo enum with character mapping tables - Delete ConversionWidthsTest (functionality now in codec tests) - Delete TestCharMapConversions (669 lines of legacy mapping tests) The refactoring eliminates approximately 3000+ lines of legacy code while maintaining full protocol compatibility and improving code maintainability. All character encoding/decoding is now handled consistently through the CharCodec and WcharCodec interfaces. --- .../org/apache/yoko/codecs/CharCodec.java | 5 +- .../org/apache/yoko/codecs/LatinCodec.java | 11 +- .../apache/yoko/codecs/SimpleCharCodec.java | 3 + .../apache/yoko/codecs/SimpleWcharCodec.java | 7 +- .../org/apache/yoko/codecs/Utf8Codec.java | 4 + .../java/org/apache/yoko/codecs/Util.java | 24 +- .../org/apache/yoko/codecs/WcharCodec.java | 4 +- .../java/org/apache/yoko/orb/CORBA/Any.java | 1138 ----------------- .../org/apache/yoko/orb/CORBA/ObjectImpl.java | 8 +- .../yoko/orb/CORBA/YokoInputStream.java | 252 ++-- .../yoko/orb/CORBA/YokoOutputStream.java | 69 +- .../org/apache/yoko/orb/OB/CharMapInfo.java | 155 --- .../java/org/apache/yoko/orb/OB/Client.java | 12 +- .../org/apache/yoko/orb/OB/ClientManager.java | 6 +- .../org/apache/yoko/orb/OB/CodeSetInfo.java | 408 +++--- .../org/apache/yoko/orb/OB/CodeSetUtil.java | 21 +- .../{CodeConverters.java => CodecPair.java} | 38 +- .../apache/yoko/orb/OB/CollocatedClient.java | 2 +- .../java/org/apache/yoko/orb/OB/Downcall.java | 8 +- .../org/apache/yoko/orb/OB/DowncallStub.java | 8 +- .../org/apache/yoko/orb/OB/GIOPClient.java | 112 +- .../apache/yoko/orb/OB/GIOPConnection.java | 8 +- .../org/apache/yoko/orb/OB/UTF8Writer.java | 53 - .../yoko/orb/OB/UnresolvedException.java | 4 +- .../java/org/apache/yoko/orb/OB/Upcall.java | 8 +- .../org/apache/yoko/UtfStringsTest.java | 6 +- .../yoko/orb/OB/ConversionWidthsTest.java | 37 - .../yoko/orb/OB/TestCharMapConversions.java | 669 ---------- 28 files changed, 519 insertions(+), 2561 deletions(-) delete mode 100644 yoko-core/src/main/java/org/apache/yoko/orb/CORBA/Any.java delete mode 100644 yoko-core/src/main/java/org/apache/yoko/orb/OB/CharMapInfo.java rename yoko-core/src/main/java/org/apache/yoko/orb/OB/{CodeConverters.java => CodecPair.java} (58%) delete mode 100644 yoko-core/src/main/java/org/apache/yoko/orb/OB/UTF8Writer.java delete mode 100644 yoko-verify/src/test/java/org/apache/yoko/orb/OB/ConversionWidthsTest.java delete mode 100644 yoko-verify/src/test/java/org/apache/yoko/orb/OB/TestCharMapConversions.java diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java index 4ffce18a2..a3333d24d 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java @@ -81,7 +81,8 @@ */ public interface CharCodec { @FunctionalInterface interface CharReader { char readChar(ReadBuffer in); } - WcharCodec NULL_CODEC = SimpleWcharCodec.NULL_CODEC; + CharCodec NULL_CHAR_CODEC = SimpleWcharCodec.NULL; + CharCodec DEFAULT_CHAR_CODEC = SimpleCharCodec.ISO_LATIN_1; /** * Get a char codec instance for the named Java charset. @@ -117,6 +118,8 @@ static CharCodec forRegistryId(int id) throws UnsupportedCharsetException { String name(); + CodeSetInfo getCodeSetInfo(); + /** * Returns true iff the encoding always uses the same number of octets per char */ diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java index 6d5e1d668..fc9eacd28 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java @@ -82,13 +82,15 @@ private interface ISO_8859_7 { String NAME = "ISO-8859-7"; LatinCodec INSTANCE = private interface ISO_8859_8 { String NAME = "ISO-8859-8"; LatinCodec INSTANCE = new LatinCodec(NAME); } private interface ISO_8859_9 { String NAME = "ISO-8859-9"; LatinCodec INSTANCE = new LatinCodec(NAME); } - final String name; - final char[] decoderArray; - final Map encoderMap; + private final String name; + private final CodeSetInfo codeSetInfo; + private final char[] decoderArray; + private final Map encoderMap; private LatinCodec(String name) { Charset cs = Charset.forName(name); this.name = cs.name(); + this.codeSetInfo = CodeSetInfo.forName(name); ByteBuffer bytes = range(0, 256) .collect(() -> allocate(256), (bb, b) -> bb.put(b, (byte) b), neverCombine()); CharBuffer chars = cs.decode(bytes); @@ -109,6 +111,9 @@ public char readChar(ReadBuffer in) { @Override public String name() { return name; } + @Override + public CodeSetInfo getCodeSetInfo() { return codeSetInfo; } + @Override public boolean equals(Object o) { if (!(o instanceof LatinCodec)) return false; diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java index b4b7305bb..06704f6ed 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleCharCodec.java @@ -20,6 +20,7 @@ import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; +import org.apache.yoko.orb.OB.CodeSetInfo; import static org.apache.yoko.codecs.Util.expect7bit; import static org.apache.yoko.codecs.Util.require7bit; @@ -27,10 +28,12 @@ enum SimpleCharCodec implements CharCodec { US_ASCII { + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.ISO_646_IRV; } public char readChar(ReadBuffer in) { return expect7bit(in.readByteAsChar()); } public void writeChar(char c, WriteBuffer out) { out.writeByte(require7bit(c)); } }, ISO_LATIN_1 { + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.ISO_LATIN_1; } public char readChar(ReadBuffer in) { return in.readByteAsChar(); } // no checking - a single-byte character can't be > 0xFF public void writeChar(char c, WriteBuffer out) { out.writeByte(require8bit(c)); } } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java index 2c24ab744..c532d1899 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java @@ -19,6 +19,7 @@ import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; +import org.apache.yoko.orb.OB.CodeSetInfo; import static org.apache.yoko.logging.VerboseLogging.DATA_IN_LOG; import static org.apache.yoko.codecs.Util.BYTE_ORDER_MARKER; @@ -28,6 +29,8 @@ enum SimpleWcharCodec implements WcharCodec { UTF_16 { + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.UTF_16; } + public int octetCount(String s) { if (s.startsWith(""+ZERO_WIDTH_NO_BREAK_SPACE)) return 2 * (s.length() + 1); return 2 * s.length(); @@ -89,10 +92,12 @@ public void writeLengthAndChar(char c, WriteBuffer out) { * This converter is for use in collocated scenarios, where the sender and the receiver * are in the same process, using the same ORB instance. *
- * It takes some shortcuts because it exchanges data with another instance of the very same class. + * It takes shortcuts because it exchanges data with another instance of the very same class. * e.g. it never writes any lengths or BOMs, so it never reads any lengths or BOMs. */ NULL { + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.NONE; } + public int octetCount(String s) { return 2 * s.length(); } public int octetCountLengthsAndWchars(int numChars) { return 2 * numChars; } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java index cd3f86cfe..42a464091 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java @@ -19,6 +19,7 @@ import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; +import org.apache.yoko.orb.OB.CodeSetInfo; import org.omg.CORBA.DATA_CONVERSION; import static java.lang.Character.highSurrogate; @@ -216,6 +217,9 @@ private static int getUtf8Len(int codepoint) { @Override public String name() { return "UTF-8"; } + @Override + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.UTF_8; } + @Override public boolean equals(Object o) { return o instanceof Utf8Codec; } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java index 37b527c2c..8401a5e2c 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java @@ -21,7 +21,7 @@ enum Util { ; /** * If any character cannot be read by a codec, the codec will return this character instead. - * Where something has gone wrong with a multi-byte encoding sequence in UTF8, + * Where something has gone wrong with a multibyte encoding sequence in UTF8, * multiple instances of this char may be returned. */ static final char UNICODE_REPLACEMENT_CHAR = '\uFFFD'; @@ -35,18 +35,24 @@ enum Util { static final char BYTE_SWAPD_MARKER = 0xFFFE; /** - * Check whether the character is US-ASCII. - * @return the character, or REPLACEMENT_CHAR if it is not US-ASCII + * Check whether the character being decoded is 7-bit. + * @return the character, or {@link #UNICODE_REPLACEMENT_CHAR} if it is not 7-bit. */ - static char expect7bit(char c) { return c <= '\u007F' ? c : Util.UNICODE_REPLACEMENT_CHAR; } + static char expect7bit(char c) { return c < (1<<7) ? c : UNICODE_REPLACEMENT_CHAR; } - /** If the character fits in 7 bits, return it, otherwise return '?' */ - static char require8bit(char c) { return c <= '\u00FF' ? c : ASCII_REPLACEMENT_CHAR; } + /** + * Check whether the character being encoded is 7-bit. + * @return the character or {@link #ASCII_REPLACEMENT_CHAR} if it is not 7-bit. + */ + static char require7bit(char c) { return c < (1<<7) ? c : ASCII_REPLACEMENT_CHAR; } - /** If the character fits in 8 bits, return it, otherwise return '?' */ - static char require7bit(char c) { return c <= '\u007F' ? c : ASCII_REPLACEMENT_CHAR; } + /** + * Check whether the character being encoded is 8-bit. + * @return the character or {@link #ASCII_REPLACEMENT_CHAR} if it is not 8-bit. + */ + static char require8bit(char c) { return c < (1<<8) ? c : ASCII_REPLACEMENT_CHAR; } - /** Find a codec by name that encodes the unicode codepoint for a char directly */ + /** Find a codec by name that encodes the Unicode codepoint for a char directly */ static CharCodec getUnicodeCodec(String name) { switch (name.toUpperCase()) { case "UTF-8": return new Utf8Codec(); diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java index c49f171b4..7bcd0b15d 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java @@ -25,7 +25,9 @@ import java.util.Optional; public interface WcharCodec extends CharCodec { - static WcharCodec getDefault() { return SimpleWcharCodec.UTF_16; } + WcharCodec NULL_WCHAR_CODEC = SimpleWcharCodec.NULL; + WcharCodec DEFAULT_WCHAR_CODEC = SimpleWcharCodec.UTF_16; + static WcharCodec getDefault() { return DEFAULT_WCHAR_CODEC; } static WcharCodec forName(String name) { return Optional.of(name) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/Any.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/Any.java deleted file mode 100644 index 13b7e0d7e..000000000 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/Any.java +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * Copyright 2026 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.CORBA; - -import org.apache.yoko.io.ReadBuffer; -import org.apache.yoko.orb.OB.ORBInstance; -import org.omg.CORBA.BAD_INV_ORDER; -import org.omg.CORBA.BAD_OPERATION; -import org.omg.CORBA.DATA_CONVERSION; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.NO_IMPLEMENT; -import org.omg.CORBA.Principal; -import org.omg.CORBA.TCKind; -import org.omg.CORBA.TypeCodePackage.BadKind; -import org.omg.CORBA.portable.Streamable; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Serializable; -import java.io.StringWriter; -import java.math.BigDecimal; -import java.util.logging.Logger; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.logging.Logger.getLogger; -import static org.apache.yoko.orb.CORBA.TypeCodeImpl._OB_convertForeignTypeCode; -import static org.apache.yoko.orb.CORBA.TypeCodeImpl._OB_getOrigType; -import static org.apache.yoko.orb.OB.TypeCodeFactory.createPrimitiveTC; -import static org.apache.yoko.util.Assert.ensure; -import static org.apache.yoko.util.Assert.fail; -import static org.apache.yoko.util.MinorCodes.MinorLocalObject; -import static org.apache.yoko.util.MinorCodes.MinorNativeNotSupported; -import static org.apache.yoko.util.MinorCodes.MinorNoAlias; -import static org.apache.yoko.util.MinorCodes.MinorNullValueNotAllowed; -import static org.apache.yoko.util.MinorCodes.MinorReadStringOverflow; -import static org.apache.yoko.util.MinorCodes.MinorReadWStringOverflow; -import static org.apache.yoko.util.MinorCodes.MinorTypeMismatch; -import static org.apache.yoko.util.MinorCodes.describeBadOperation; -import static org.apache.yoko.util.MinorCodes.describeDataConversion; -import static org.apache.yoko.util.MinorCodes.describeMarshal; -import static org.omg.CORBA.CompletionStatus.COMPLETED_NO; -import static org.omg.CORBA.TCKind._tk_Principal; -import static org.omg.CORBA.TCKind._tk_TypeCode; -import static org.omg.CORBA.TCKind._tk_abstract_interface; -import static org.omg.CORBA.TCKind._tk_alias; -import static org.omg.CORBA.TCKind._tk_any; -import static org.omg.CORBA.TCKind._tk_array; -import static org.omg.CORBA.TCKind._tk_boolean; -import static org.omg.CORBA.TCKind._tk_char; -import static org.omg.CORBA.TCKind._tk_double; -import static org.omg.CORBA.TCKind._tk_enum; -import static org.omg.CORBA.TCKind._tk_except; -import static org.omg.CORBA.TCKind._tk_fixed; -import static org.omg.CORBA.TCKind._tk_float; -import static org.omg.CORBA.TCKind._tk_long; -import static org.omg.CORBA.TCKind._tk_longlong; -import static org.omg.CORBA.TCKind._tk_native; -import static org.omg.CORBA.TCKind._tk_null; -import static org.omg.CORBA.TCKind._tk_objref; -import static org.omg.CORBA.TCKind._tk_octet; -import static org.omg.CORBA.TCKind._tk_sequence; -import static org.omg.CORBA.TCKind._tk_short; -import static org.omg.CORBA.TCKind._tk_string; -import static org.omg.CORBA.TCKind._tk_struct; -import static org.omg.CORBA.TCKind._tk_ulong; -import static org.omg.CORBA.TCKind._tk_ulonglong; -import static org.omg.CORBA.TCKind._tk_union; -import static org.omg.CORBA.TCKind._tk_ushort; -import static org.omg.CORBA.TCKind._tk_value; -import static org.omg.CORBA.TCKind._tk_value_box; -import static org.omg.CORBA.TCKind._tk_void; -import static org.omg.CORBA.TCKind._tk_wchar; -import static org.omg.CORBA.TCKind._tk_wstring; -import static org.omg.CORBA.TCKind.tk_TypeCode; -import static org.omg.CORBA.TCKind.tk_abstract_interface; -import static org.omg.CORBA.TCKind.tk_any; -import static org.omg.CORBA.TCKind.tk_boolean; -import static org.omg.CORBA.TCKind.tk_char; -import static org.omg.CORBA.TCKind.tk_double; -import static org.omg.CORBA.TCKind.tk_fixed; -import static org.omg.CORBA.TCKind.tk_float; -import static org.omg.CORBA.TCKind.tk_long; -import static org.omg.CORBA.TCKind.tk_longlong; -import static org.omg.CORBA.TCKind.tk_null; -import static org.omg.CORBA.TCKind.tk_objref; -import static org.omg.CORBA.TCKind.tk_octet; -import static org.omg.CORBA.TCKind.tk_short; -import static org.omg.CORBA.TCKind.tk_string; -import static org.omg.CORBA.TCKind.tk_ulong; -import static org.omg.CORBA.TCKind.tk_ulonglong; -import static org.omg.CORBA.TCKind.tk_ushort; -import static org.omg.CORBA.TCKind.tk_value; -import static org.omg.CORBA.TCKind.tk_value_box; -import static org.omg.CORBA.TCKind.tk_wchar; -import static org.omg.CORBA.TCKind.tk_wstring; -import static org.omg.CORBA_2_4.TCKind._tk_local_interface; -import static org.omg.CORBA_2_4.TCKind.tk_local_interface; - -final public class Any extends org.omg.CORBA.Any { - private static final Logger logger = getLogger(Any.class.getName()); - - private ORBInstance orbInstance; - private org.omg.CORBA.TypeCode typeCode; - private TypeCodeImpl yokoTypeCode; - private TypeCodeImpl origTypeCode; - private Object value; - - @Override - public String toString() { - try (StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw)) { - pw.println("Any {"); - pw.printf("\t%s = %s%n", "tc", typeCode); - pw.printf("\t%s = %s%n", "ytc", equalTypeCodes(yokoTypeCode, typeCode) ? "tc" : yokoTypeCode); - pw.printf("\t%s = %s%n", "otc", equalTypeCodes(origTypeCode, typeCode) ? "tc" : equalTypeCodes(origTypeCode, yokoTypeCode) ? "ytc" : origTypeCode); - pw.printf("\t%s = %s%n", "value", value); - pw.println("}"); - return sw.toString(); - } catch(IOException ignored) { return "Any { ???? }"; } - } - - private boolean equalTypeCodes(org.omg.CORBA.TypeCode tc1, org.omg.CORBA.TypeCode tc2) { - try { - return (null != tc1) && tc1.equal(tc2); - } catch (Throwable t) { return false; } - } - - private void checkValue(TCKind kind) throws BAD_OPERATION { - if (!requireNonNull(kind).equals(origTypeCode.kind())) - throw new BAD_OPERATION(describeBadOperation(MinorTypeMismatch), MinorTypeMismatch, COMPLETED_NO); - if (null == value) - throw new BAD_OPERATION(describeBadOperation(MinorNullValueNotAllowed), MinorNullValueNotAllowed, COMPLETED_NO); - } - - private void setType(org.omg.CORBA.TypeCode tc) { - // Save the original TypeCode. Note that this TypeCode - // could have been created by another ORB. Also note that - // DII-based portable stubs (such as those built into the - // JDK in 1.2/1.3) use the equals() method to compare - // TypeCodes, so we *must* preserve the original. - typeCode = tc; - - // Get an equivalent Yoko TypeCode - yokoTypeCode = tc instanceof TypeCodeImpl ? (TypeCodeImpl) tc : _OB_convertForeignTypeCode(tc); - - // - // Cache the unaliased TypeCode - // - origTypeCode = _OB_getOrigType(yokoTypeCode); - } - - private void readValue(org.omg.CORBA.portable.InputStream in) throws MARSHAL { - final int kind = origTypeCode.kind().value(); - - logger.fine("Reading ANY value of kind " + kind); - // - // Spec says that calling read_value when a Streamable has - // previously been inserted will update the Streamable - // - if (value instanceof Streamable - && kind != _tk_value - && kind != _tk_value_box - && kind != _tk_abstract_interface) { - ((Streamable) value)._read(in); - return; - } - - switch (kind) { - case _tk_null: - case _tk_void: - value = null; - break; - - case _tk_short: - value = (int) in.read_short(); - break; - - case _tk_long: - value = in.read_long(); - break; - - case _tk_longlong: - value = in.read_longlong(); - break; - - case _tk_ushort: - value = (int) in.read_ushort(); - break; - - case _tk_ulong: - - case _tk_enum: - value = in.read_ulong(); - break; - - case _tk_ulonglong: - value = in.read_ulonglong(); - break; - - case _tk_float: - value = in.read_float(); - break; - - case _tk_double: - value = in.read_double(); - break; - - case _tk_boolean: - value = in.read_boolean(); - break; - - case _tk_char: - value = in.read_char(); - break; - - case _tk_wchar: - value = in.read_wchar(); - break; - - case _tk_octet: - value = in.read_octet(); - break; - - case _tk_any: - value = in.read_any(); - break; - - case _tk_TypeCode: - value = in.read_TypeCode(); - break; - - case _tk_Principal: - value = in.read_Principal(); - break; - - case _tk_objref: - value = in.read_Object(); - break; - - case _tk_struct: - case _tk_except: - case _tk_union: - case _tk_sequence: - case _tk_array: { - try (YokoOutputStream out = new YokoOutputStream()) { - out._OB_ORBInstance(orbInstance); - out.write_InputStream(in, origTypeCode); - value = out.create_input_stream(); - } - break; - } - - case _tk_value: - case _tk_value_box: - case _tk_abstract_interface: { - try { - YokoInputStream is = (YokoInputStream) in; - is.read_value(this, typeCode); - } catch (ClassCastException ex) { - try { - org.omg.CORBA_2_3.portable.InputStream is = (org.omg.CORBA_2_3.portable.InputStream) in; - value = is.read_value(typeCode.id()); - } catch (BadKind e) { - throw fail(e); - } - } - break; - } - - case _tk_string: { - try { - String str = in.read_string(); - int len = origTypeCode.length(); - if (len != 0 && str.length() > len) - throw new MARSHAL(format("string length (%d) exceeds bound (%d)", str.length(), len), MinorReadStringOverflow, COMPLETED_NO); - value = str; - } catch (BadKind ex) { - throw fail(ex); - } - break; - } - - case _tk_wstring: { - try { - String str = in.read_wstring(); - int len = origTypeCode.length(); - if (len != 0 && str.length() > len) - throw new MARSHAL(format("wstring length (%d) exceeds bound (%d)", str.length(), len), MinorReadWStringOverflow, COMPLETED_NO); - value = str; - } catch (BadKind ex) { - throw fail(ex); - } - break; - } - - case _tk_fixed: { - try { - value = in.read_fixed().movePointLeft(origTypeCode.fixed_scale()); - } catch (BadKind ex) { - throw fail(ex); - } - - break; - } - - case _tk_native: - throw new MARSHAL( - describeMarshal(MinorNativeNotSupported), MinorNativeNotSupported, COMPLETED_NO); - - case _tk_local_interface: - throw new MARSHAL(describeMarshal(MinorLocalObject), MinorLocalObject, COMPLETED_NO); - - case _tk_alias: - default: - throw new DATA_CONVERSION(describeDataConversion(MinorNoAlias), MinorNoAlias, COMPLETED_NO); - } - } - - private void copyFrom(Any any) { - orbInstance = any.orbInstance; - typeCode = any.typeCode; - yokoTypeCode = any.yokoTypeCode; - origTypeCode = any.origTypeCode; - - if (any.value instanceof Streamable) { - readValue(any.create_input_stream()); - return; - } - - if (any.value == null) { - value = null; - return; - } - - int kind = origTypeCode.kind().value(); - switch (kind) { - case _tk_null: - case _tk_void: - case _tk_short: - case _tk_long: - case _tk_longlong: - case _tk_ushort: - case _tk_ulong: - case _tk_ulonglong: - case _tk_float: - case _tk_double: - case _tk_boolean: - case _tk_char: - case _tk_wchar: - case _tk_octet: - case _tk_enum: - case _tk_string: - case _tk_wstring: - case _tk_fixed: - case _tk_TypeCode: - case _tk_Principal: - case _tk_objref: - case _tk_local_interface: - - case _tk_native: - value = any.value; - break; - - case _tk_any: - case _tk_struct: - case _tk_except: - case _tk_union: - case _tk_sequence: - case _tk_array: - readValue(any.create_input_stream()); - break; - - case _tk_value: - case _tk_value_box: - case _tk_abstract_interface: - if (any.value instanceof YokoInputStream) - readValue(any.create_input_stream()); - else - value = any.value; - break; - - case _tk_alias: - default: - throw fail("tk_alias not supported for copying"); - } - } - - // ------------------------------------------------------------------ - // Standard IDL to Java Mapping - // ------------------------------------------------------------------ - - public synchronized boolean equal(org.omg.CORBA.Any a) { - if (a == null) - return false; - - if (this == a) - return true; - - if (!typeCode.equal(a.type())) - return false; - - Any any; - try { - any = (Any) a; - } catch (ClassCastException ex) { - // - // Argument may have been created by a foreign singleton ORB, - // so we'll use a temporary. - // - any = new Any(a); - } - - if (value == any.value) - return true; - - if (value == null || any.value == null) - return false; - - if (value instanceof Streamable && any.value instanceof Streamable) { - YokoOutputStream os1 = (YokoOutputStream) create_output_stream(); - ((Streamable) value)._write(os1); - YokoOutputStream os2 = (YokoOutputStream) create_output_stream(); - ((Streamable) any.value)._write(os2); - return os1.writtenBytesEqual(os2); - } - - int kind = origTypeCode.kind().value(); - switch (kind) { - case _tk_null: - case _tk_void: - return true; - - case _tk_short: - case _tk_long: - case _tk_longlong: - case _tk_ushort: - case _tk_ulong: - case _tk_ulonglong: - case _tk_float: - case _tk_double: - case _tk_boolean: - case _tk_char: - case _tk_wchar: - case _tk_octet: - case _tk_enum: - case _tk_string: - case _tk_wstring: - case _tk_fixed: - return value.equals(any.value); - - case _tk_any: - return extract_any().equal(any.extract_any()); - - case _tk_TypeCode: - return extract_TypeCode().equal(any.extract_TypeCode()); - - case _tk_Principal: - return extract_Principal().equals(any.extract_Principal()); - - case _tk_objref: - case _tk_local_interface: - return extract_Object()._is_equivalent(any.extract_Object()); - - case _tk_struct: - case _tk_except: - case _tk_union: - case _tk_sequence: - case _tk_array: { - return compareValuesAsInputStreams(this, any); - } - - case _tk_value: - case _tk_value_box: { - if (value instanceof YokoInputStream && any.value instanceof YokoInputStream) { - return compareValuesAsInputStreams(this, any); - } else - return false; - } - - case _tk_abstract_interface: { - if (value instanceof org.omg.CORBA.Object && any.value instanceof org.omg.CORBA.Object) { - return extract_Object()._is_equivalent(any.extract_Object()); - } else if (value instanceof YokoInputStream && any.value instanceof YokoInputStream) { - return compareValuesAsInputStreams(this, any); - } - return false; - } - - case _tk_native: - return (value == any.value); - - case _tk_alias: - default: - throw fail("tk_alias not supported for comparison"); - } - } - - private static boolean compareValuesAsInputStreams(Any any1, Any any2) { - ReadBuffer buf1 = ((YokoInputStream) any1.value).getBuffer(); - ReadBuffer buf2 = ((YokoInputStream) any2.value).getBuffer(); - return buf1.dataEquals(buf2); - } - - public synchronized org.omg.CORBA.TypeCode type() { - return typeCode; - } - - public synchronized void type(org.omg.CORBA.TypeCode tc) { - setType(tc); - value = null; - } - - public synchronized void read_value(org.omg.CORBA.portable.InputStream in, org.omg.CORBA.TypeCode tc) throws MARSHAL { - setType(tc); - readValue(in); - } - - public synchronized void write_value(org.omg.CORBA.portable.OutputStream out) { - int kind = origTypeCode.kind().value(); - - if (value instanceof Streamable - && kind != _tk_value - && kind != _tk_value_box - && kind != _tk_abstract_interface) { - ((Streamable) value)._write(out); - return; - } - - switch (kind) { - case _tk_null: - case _tk_void: - break; - - case _tk_short: - out.write_short(((Integer) value).shortValue()); - break; - - case _tk_long: - out.write_long((Integer) value); - break; - - case _tk_longlong: - out.write_longlong((Long) value); - break; - - case _tk_ushort: - out.write_ushort(((Integer) value).shortValue()); - break; - - case _tk_ulong: - - case _tk_enum: - out.write_ulong((Integer) value); - break; - - case _tk_ulonglong: - out.write_ulonglong((Long) value); - break; - - case _tk_float: - out.write_float((Float) value); - break; - - case _tk_double: - out.write_double((Double) value); - break; - - case _tk_boolean: - out.write_boolean((Boolean) value); - break; - - case _tk_char: - out.write_char((Character) value); - break; - - case _tk_wchar: - out.write_wchar((Character) value); - break; - - case _tk_octet: - out.write_octet((Byte) value); - break; - - case _tk_any: - out.write_any((org.omg.CORBA.Any) value); - break; - - case _tk_TypeCode: - out.write_TypeCode((org.omg.CORBA.TypeCode) value); - break; - - case _tk_Principal: - out.write_Principal((Principal) value); - break; - - case _tk_objref: - out.write_Object((org.omg.CORBA.Object) value); - break; - - case _tk_struct: - case _tk_except: - case _tk_union: - case _tk_sequence: - case _tk_array: { - YokoOutputStream o = (YokoOutputStream) out; - YokoInputStream in = (YokoInputStream) value; - in._OB_reset(); - o.write_InputStream(in, typeCode); - break; - } - - case _tk_value: { - YokoOutputStream o = (YokoOutputStream) out; - if (value instanceof YokoInputStream) { - YokoInputStream in = (YokoInputStream) value; - in._OB_reset(); - o.write_InputStream(in, typeCode); - } else - o.write_value((Serializable) value); - break; - } - - case _tk_value_box: { - YokoOutputStream o = (YokoOutputStream) out; - if (value instanceof YokoInputStream) { - YokoInputStream in = (YokoInputStream) value; - in._OB_reset(); - o.write_InputStream(in, typeCode); - } else { - o.write_value((Serializable) value, origTypeCode, null); - } - break; - } - - case _tk_string: - out.write_string((String) value); - break; - - case _tk_wstring: - out.write_wstring((String) value); - break; - - case _tk_fixed: { - // TODO: check ranges here? compare scale against TypeCode? - try { - out.write_fixed(((BigDecimal) value).movePointRight(origTypeCode.fixed_scale())); - } catch (BadKind ex) { - throw fail(ex); - } - - break; - } - - case _tk_abstract_interface: { - YokoOutputStream o = (YokoOutputStream) out; - if (value != null && value instanceof YokoInputStream) { - YokoInputStream in = (YokoInputStream) value; - in._OB_reset(); - ensure(!in.read_boolean()); - o.write_abstract_interface(in.read_value()); - } else - o.write_abstract_interface(value); - break; - } - - case _tk_native: - throw new MARSHAL(describeMarshal(MinorNativeNotSupported), MinorNativeNotSupported, COMPLETED_NO); - - case _tk_local_interface: - throw new MARSHAL(describeMarshal(MinorLocalObject), MinorLocalObject, COMPLETED_NO); - - case _tk_alias: - default: - throw fail("unable to write tk_alias types"); - } - } - - public synchronized org.omg.CORBA.portable.OutputStream create_output_stream() { - // TODO: - // Spec says that calling create_output_stream and - // writing to the any will update the state of the - // last streamable object, if present. - YokoOutputStream out = new YokoOutputStream(); - out._OB_ORBInstance(orbInstance); - return out; - } - - public synchronized org.omg.CORBA.portable.InputStream create_input_stream() { - if (value instanceof YokoInputStream) { - return new YokoInputStream(((YokoInputStream) value)); - } else { - try (YokoOutputStream out = new YokoOutputStream()) { - out._OB_ORBInstance(orbInstance); - write_value(out); - return out.create_input_stream(); - } - } - } - - public synchronized short extract_short() throws BAD_OPERATION { - checkValue(tk_short); - return ((Integer) value).shortValue(); - } - - public synchronized void insert_short(short val) { - type(createPrimitiveTC(tk_short)); - value = (int) val; - } - - public synchronized int extract_long() throws BAD_OPERATION { - checkValue(tk_long); - return (Integer) value; - } - - public synchronized void insert_long(int val) { - type(createPrimitiveTC(tk_long)); - value = val; - } - - public synchronized long extract_longlong() throws BAD_OPERATION { - checkValue(tk_longlong); - return (Long) value; - } - - public synchronized void insert_longlong(long val) { - type(createPrimitiveTC(tk_longlong)); - value = val; - } - - public synchronized short extract_ushort() throws BAD_OPERATION { - checkValue(tk_ushort); - return ((Integer) value).shortValue(); - } - - public synchronized void insert_ushort(short val) { - type(createPrimitiveTC(tk_ushort)); - value = (int) val; - } - - public synchronized int extract_ulong() throws BAD_OPERATION { - checkValue(tk_ulong); - return (Integer) value; - } - - public synchronized void insert_ulong(int val) { - type(createPrimitiveTC(tk_ulong)); - value = val; - } - - public synchronized long extract_ulonglong() throws BAD_OPERATION { - checkValue(tk_ulonglong); - return (Long) value; - } - - public synchronized void insert_ulonglong(long val) { - type(createPrimitiveTC(tk_ulonglong)); - value = val; - } - - public synchronized boolean extract_boolean() throws BAD_OPERATION { - checkValue(tk_boolean); - return (Boolean) value; - } - - public synchronized void insert_boolean(boolean val) { - type(createPrimitiveTC(tk_boolean)); - value = val; - } - - public synchronized char extract_char() throws BAD_OPERATION { - checkValue(tk_char); - return (Character) value; - } - - public synchronized void insert_char(char val) throws DATA_CONVERSION { - type(createPrimitiveTC(tk_char)); - value = val; - } - - public synchronized char extract_wchar() throws BAD_OPERATION { - checkValue(tk_wchar); - return (Character) value; - } - - public synchronized void insert_wchar(char val) throws DATA_CONVERSION { - type(createPrimitiveTC(tk_wchar)); - value = val; - } - - public synchronized byte extract_octet() throws BAD_OPERATION { - checkValue(tk_octet); - return (Byte) value; - } - - public synchronized void insert_octet(byte val) { - type(createPrimitiveTC(tk_octet)); - value = val; - } - - public synchronized float extract_float() throws BAD_OPERATION { - checkValue(tk_float); - return (Float) value; - } - - public synchronized void insert_float(float val) { - type(createPrimitiveTC(tk_float)); - value = val; - } - - public synchronized double extract_double() throws BAD_OPERATION { - checkValue(tk_double); - return (Double) value; - } - - public synchronized void insert_double(double val) { - type(createPrimitiveTC(tk_double)); - value = val; - } - - public synchronized org.omg.CORBA.Any extract_any() throws BAD_OPERATION { - checkValue(tk_any); - return (org.omg.CORBA.Any) value; - } - - public synchronized void insert_any(org.omg.CORBA.Any val) { - type(createPrimitiveTC(tk_any)); - value = val; - } - - public synchronized org.omg.CORBA.TypeCode extract_TypeCode() throws BAD_OPERATION { - checkValue(tk_TypeCode); - return (org.omg.CORBA.TypeCode) value; - } - - public synchronized void insert_TypeCode(org.omg.CORBA.TypeCode val) { - type(createPrimitiveTC(tk_TypeCode)); - value = val; - } - - public synchronized Principal extract_Principal() throws BAD_OPERATION { - // Deprecated by CORBA 2.2 - throw new NO_IMPLEMENT(); - } - - public synchronized void insert_Principal(Principal val) { - // Deprecated by CORBA 2.2 - throw new NO_IMPLEMENT(); - } - - public synchronized org.omg.CORBA.Object extract_Object() throws BAD_OPERATION { - TCKind kind = origTypeCode.kind(); - if (kind != tk_objref && kind != tk_abstract_interface && kind != tk_local_interface) { - throw new BAD_OPERATION(describeBadOperation(MinorTypeMismatch), MinorTypeMismatch, COMPLETED_NO); - } - - if (value != null && !(value instanceof org.omg.CORBA.Object)) { - throw new BAD_OPERATION(describeBadOperation(MinorTypeMismatch), MinorTypeMismatch, COMPLETED_NO); - } - - return (org.omg.CORBA.Object) value; - } - - public synchronized void insert_Object(org.omg.CORBA.Object val) { - // - // If we don't have an ORB instance, then try to get one from - // the object reference - // - if (null == orbInstance && null != val) { - try { - Delegate d = (Delegate) ((org.omg.CORBA.portable.ObjectImpl) val)._get_delegate(); - orbInstance = d._OB_ORBInstance(); - } catch (BAD_OPERATION ignored) { - // Object has no delegate - ignore - } - } - - org.omg.CORBA.TypeCode tc = createPrimitiveTC(tk_objref); - insert_Object(val, tc); - } - - public synchronized void insert_Object(org.omg.CORBA.Object val, - org.omg.CORBA.TypeCode tc) { - // - // If we don't have an ORB instance, then try to get one from - // the object reference - // - if (null == orbInstance && null != val) { - try { - Delegate d = (Delegate) ((org.omg.CORBA.portable.ObjectImpl) val)._get_delegate(); - orbInstance = d._OB_ORBInstance(); - } catch (BAD_OPERATION ignored) { - // Object has no delegate - ignore - } - } - - type(tc); - value = val; - } - - public synchronized String extract_string() throws BAD_OPERATION { - checkValue(tk_string); - return (String) value; - } - - public synchronized void insert_string(String val) { - type(createPrimitiveTC(tk_string)); - value = val; - } - - public synchronized String extract_wstring() throws BAD_OPERATION { - checkValue(tk_wstring); - return (String) value; - } - - public synchronized void insert_wstring(String val) { - type(createPrimitiveTC(tk_wstring)); - value = val; - } - - public Streamable extract_Streamable() throws BAD_INV_ORDER { - if (!(value instanceof Streamable)) throw new BAD_INV_ORDER("Type mismatch"); - return (Streamable) value; - } - - public synchronized void insert_Streamable(Streamable val) { - type(val._type()); - value = val; - } - - public synchronized BigDecimal extract_fixed() { - checkValue(tk_fixed); - return (BigDecimal) value; - } - - public synchronized void insert_fixed(BigDecimal val) { - type(createPrimitiveTC(tk_fixed)); - value = val; - } - - public synchronized void insert_fixed(BigDecimal val, org.omg.CORBA.TypeCode tc) throws BAD_INV_ORDER { - type(tc); - value = val; - } - - public Serializable extract_Value() throws BAD_OPERATION { - TCKind kind = origTypeCode.kind(); - - if (tk_value != kind && tk_value_box != kind && tk_abstract_interface != kind) { - throw new BAD_OPERATION(describeBadOperation(MinorTypeMismatch), MinorTypeMismatch, COMPLETED_NO); - } - - if (tk_abstract_interface == kind && value instanceof org.omg.CORBA.Object) { - throw new BAD_OPERATION(describeBadOperation(MinorTypeMismatch), MinorTypeMismatch, COMPLETED_NO); - } - - if (value instanceof YokoInputStream) { - YokoInputStream in = (YokoInputStream) value; - in._OB_reset(); - if (kind == tk_abstract_interface) ensure(!in.read_boolean()); - return in.read_value(); - } else - return (Serializable) value; - } - - public synchronized void insert_Value(Serializable val) { - org.omg.CORBA.TypeCode tc = createPrimitiveTC(tk_value); - insert_Value(val, tc); - } - - public synchronized void insert_Value(Serializable val, org.omg.CORBA.TypeCode tc) throws MARSHAL { - type(tc); - - value = val; - } - - // ------------------------------------------------------------------ - // Yoko internal functions - // Application programs must not use these functions directly - // ------------------------------------------------------------------ - - public Any() { - this((ORBInstance) null); - } - - public Any(ORBInstance orbInstance) { - this.orbInstance = orbInstance; - type(createPrimitiveTC(tk_null)); - value = null; - } - - public Any(Any any) { - copyFrom(any); - } - - public Any(org.omg.CORBA.Any any) { - // - // This constructor creates a new Any using the standard interface - // - - // - // Optimization - // - if (any instanceof Any) { - copyFrom((Any) any); - return; - } - - orbInstance = null; - setType(any.type()); - - switch (origTypeCode.kind().value()) { - case _tk_null: - case _tk_void: - case _tk_Principal: - break; - - case _tk_short: - value = (int) any.extract_short(); - break; - - case _tk_long: - value = any.extract_long(); - break; - - case _tk_longlong: - value = any.extract_longlong(); - break; - - case _tk_ushort: - value = (int) any.extract_ushort(); - break; - - case _tk_ulong: - value = any.extract_ulong(); - break; - - case _tk_ulonglong: - value = any.extract_ulonglong(); - break; - - case _tk_float: - value = any.extract_float(); - break; - - case _tk_double: - value = any.extract_double(); - break; - - case _tk_boolean: - value = any.extract_boolean(); - break; - - case _tk_char: - value = any.extract_char(); - break; - - case _tk_wchar: - value = any.extract_wchar(); - break; - - case _tk_octet: - value = any.extract_octet(); - break; - - case _tk_string: - value = any.extract_string(); - break; - - case _tk_wstring: - value = any.extract_wstring(); - break; - - case _tk_fixed: - value = any.extract_fixed(); - break; - - case _tk_TypeCode: - value = any.extract_TypeCode(); - break; - - case _tk_objref: - case _tk_abstract_interface: - case _tk_local_interface: - try { - value = any.extract_Object(); - break; - } catch (BAD_OPERATION ex) { - // - // Any must hold an abstract interface representing - // a valuetype, so fall through to default case - // - } - - default: - readValue(any.create_input_stream()); - break; - } - } - - public Any(ORBInstance orbInstance, org.omg.CORBA.TypeCode type, Object value) { - this.orbInstance = orbInstance; - setType(type); - this.value = value; - } - - public synchronized Object value() { - return value; - } - - public synchronized void replace(org.omg.CORBA.TypeCode tc, Object value) { - setType(tc); - this.value = value; - } - - public synchronized void _OB_ORBInstance(ORBInstance orbInstance) { - this.orbInstance = orbInstance; - } - - public synchronized org.omg.CORBA.TypeCode _OB_type() { - return yokoTypeCode; - } -} diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java index 59bb00733..16e594603 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/ObjectImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ */ package org.apache.yoko.orb.CORBA; -import org.apache.yoko.orb.OB.CodeConverters; +import org.apache.yoko.orb.OB.CodecPair; import org.apache.yoko.orb.OB.DowncallStub; import org.apache.yoko.orb.OB.FailureException; import org.apache.yoko.orb.OB.GIOPOutgoingMessage; @@ -83,7 +83,7 @@ public void _OB_ami_router_postMarshal( } // public org.apache.yoko.orb.CORBA.OutputStream - public CodeConverters _OB_setup_ami_poll_request( + public CodecPair _OB_setup_ami_poll_request( ServiceContextListHolder sclHolder, OutputStreamHolder out) { Delegate delegate = (Delegate) _get_delegate(); @@ -91,7 +91,7 @@ public CodeConverters _OB_setup_ami_poll_request( try { DowncallStub downStub = delegate ._OB_getDowncallStub(); - CodeConverters cc = downStub + CodecPair cc = downStub .setupPollingRequest(sclHolder, out); return cc; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java index 423d93b91..71cfe7e12 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java @@ -24,7 +24,7 @@ import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.orb.OB.CodeBaseProxy; -import org.apache.yoko.orb.OB.CodeConverters; +import org.apache.yoko.orb.OB.CodecPair; import org.apache.yoko.orb.OB.ORBInstance; import org.apache.yoko.orb.OB.ObjectFactory; import org.apache.yoko.orb.OB.TypeCodeCache; @@ -32,6 +32,7 @@ import org.apache.yoko.orb.OCI.GiopVersion; import org.apache.yoko.rmi.impl.InputStreamWithOffsets; import org.apache.yoko.util.Assert; +import org.omg.CORBA.Any; import org.omg.CORBA.BAD_TYPECODE; import org.omg.CORBA.INITIALIZE; import org.omg.CORBA.MARSHAL; @@ -79,7 +80,6 @@ import static org.apache.yoko.util.MinorCodes.MinorLoadStub; import static org.apache.yoko.util.MinorCodes.MinorReadBooleanArrayOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadBooleanOverflow; -import static org.apache.yoko.util.MinorCodes.MinorReadCharArrayOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadCharOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadDoubleArrayOverflow; import static org.apache.yoko.util.MinorCodes.MinorReadDoubleOverflow; @@ -152,30 +152,30 @@ final public class YokoInputStream extends InputStreamWithOffsets { private static final Logger logger = DATA_IN_LOG; - private ORBInstance orbInstance_; + private ORBInstance orbInstance; private final ReadBuffer readBuffer; - boolean swap_; + boolean swapBytes; - private GiopVersion giopVersion_ = GIOP1_0; + private GiopVersion giopVersion = GIOP1_0; - private final int origPos_; + private final int origPos; - private final boolean origSwap_; + private final boolean origSwap; // // Handles all OBV marshaling // - private ValueReader valueReader_; + private ValueReader valueReader; - private TypeCodeCache cache_; + private TypeCodeCache cache; - private CodeConverters codeConverters_; + private CodecPair codecs; - private CodeBase sendingContextRuntime_; + private CodeBase sendingContextRuntime; - private String codebase_; + private String codebase; // ------------------------------------------------------------------ // Private and protected members @@ -185,7 +185,7 @@ private TypeCodeImpl checkCache(String id, int startPos, int length) { TypeCodeImpl tc = null; if (!id.isEmpty()) { - tc = cache_.get(id); + tc = cache.get(id); if (tc != null) { _OB_skip(length + startPos - readBuffer.getPosition()); } @@ -250,22 +250,22 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { tc = (TypeCodeImpl) createInterfaceTC(id, read_string()); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } history.put(oldPos, tc); - swap_ = swap; + this.swapBytes = swap; break; } @@ -277,12 +277,12 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { // @@ -305,11 +305,11 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool tc = p; - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -320,12 +320,12 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { // @@ -392,11 +392,11 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool tc = p; - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -407,12 +407,12 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { String name = read_string(); @@ -423,11 +423,11 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool tc = (TypeCodeImpl) createEnumTC(id, name, members); history.put(oldPos, tc); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -446,7 +446,7 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool case _tk_sequence : case _tk_array : { read_ulong(); // encapsulation length - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); // @@ -462,7 +462,7 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool tc = p; - swap_ = swap; + this.swapBytes = swap; break; } @@ -473,23 +473,23 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { tc = (TypeCodeImpl) createAliasTC(id, read_string(), readTypeCodeImpl(history, false)); history.put(oldPos, tc); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -500,12 +500,12 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { // @@ -534,11 +534,11 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool tc = p; - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -549,22 +549,22 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { tc = (TypeCodeImpl) createValueBoxTC(id, read_string(), readTypeCodeImpl(history, false)); history.put(oldPos, tc); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -575,7 +575,7 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); @@ -583,17 +583,17 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool if (logger.isLoggable(Level.FINE)) logger.fine(String.format("Abstract interface typecode encapsulation length=0x%x id=%s", length, id)); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { tc = (TypeCodeImpl) createAbstractInterfaceTC(id, read_string()); history.put(oldPos, tc); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -604,22 +604,22 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { tc = (TypeCodeImpl) createNativeTC(id, read_string()); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } history.put(oldPos, tc); - swap_ = swap; + this.swapBytes = swap; break; } @@ -630,22 +630,22 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool // read. checkChunk(); int typePos = readBuffer.getPosition(); - boolean swap = swap_; + boolean swap = this.swapBytes; _OB_readEndian(); String id = read_string(); - if (isTopLevel && cache_ != null) + if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos if (tc == null) { tc = (TypeCodeImpl) createLocalInterfaceTC(id, read_string()); history.put(oldPos, tc); - if (!id.isEmpty() && cache_ != null) - cache_.put(id, tc); + if (!id.isEmpty() && cache != null) + cache.put(id, tc); } - swap_ = swap; + this.swapBytes = swap; break; } @@ -657,7 +657,7 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool return tc; } - private ValueReader valueReader() { return valueReader_ == null ? (valueReader_ = new ValueReader(this)) : valueReader_; } + private ValueReader valueReader() { return valueReader == null ? (valueReader = new ValueReader(this)) : valueReader; } public int available() { int available = readBuffer.available(); @@ -671,7 +671,7 @@ public int read() { } public org.omg.CORBA.ORB orb() { - return orbInstance_ == null ? null : orbInstance_.getORB(); + return orbInstance == null ? null : orbInstance.getORB(); } public boolean read_boolean() { @@ -694,7 +694,7 @@ private static boolean toBoolean(byte b) { public char read_char() { checkChunk(); try { - return codeConverters_.charCodec.readChar(readBuffer); + return codecs.charCodec.readChar(readBuffer); } catch (IndexOutOfBoundsException e) { throw newMarshalError(MinorReadCharOverflow, e); } @@ -703,13 +703,13 @@ public char read_char() { public char read_wchar() { checkChunk(); try { - switch (giopVersion_) { + switch (giopVersion) { case GIOP1_0: case GIOP1_1: readBuffer.align(TWO_BYTE_BOUNDARY); - return codeConverters_.wcharCodec.readCharWithEndianFlag(readBuffer, swap_); + return codecs.wcharCodec.readCharWithEndianFlag(readBuffer, swapBytes); default: - return codeConverters_.wcharCodec.readLengthAndChar(readBuffer); + return codecs.wcharCodec.readLengthAndChar(readBuffer); } } catch (IndexOutOfBoundsException e) { throw newMarshalError(MinorReadWCharOverflow, e); @@ -729,7 +729,7 @@ public short read_short() { checkChunk(); readBuffer.align(TWO_BYTE_BOUNDARY); try { - return swap_ ? readBuffer.readShort_LE() : readBuffer.readShort(); + return swapBytes ? readBuffer.readShort_LE() : readBuffer.readShort(); } catch (IndexOutOfBoundsException e) { throw newMarshalError((MinorReadShortOverflow), e); } @@ -759,7 +759,7 @@ public long read_longlong() { checkChunk(); readBuffer.align(EIGHT_BYTE_BOUNDARY); try { - return swap_ ? readBuffer.readLong_LE() : readBuffer.readLong(); + return swapBytes ? readBuffer.readLong_LE() : readBuffer.readLong(); } catch (IndexOutOfBoundsException e) { throw newMarshalError((MinorReadLongLongOverflow), e); } @@ -777,7 +777,7 @@ public float read_float() { checkChunk(); readBuffer.align(FOUR_BYTE_BOUNDARY); try { - return swap_ ? readBuffer.readFloat_LE() : readBuffer.readFloat(); + return swapBytes ? readBuffer.readFloat_LE() : readBuffer.readFloat(); } catch (IndexOutOfBoundsException e) { throw newMarshalError((MinorReadFloatOverflow), e); } @@ -787,7 +787,7 @@ public double read_double() { checkChunk(); readBuffer.align(EIGHT_BYTE_BOUNDARY); try { - return swap_ ? readBuffer.readDouble_LE() : readBuffer.readDouble(); + return swapBytes ? readBuffer.readDouble_LE() : readBuffer.readDouble(); } catch (IndexOutOfBoundsException e) { throw newMarshalError((MinorReadDoubleOverflow), e); } @@ -812,7 +812,7 @@ public String read_string() { // Java strings don't need null terminators, so our string length will be at most one less than the byte count StringBuilder sb = new StringBuilder(byteCount - 1); - final CharCodec codec = codeConverters_.charCodec; + final CharCodec codec = codecs.charCodec; final int endPosition = readBuffer.getPosition() + byteCount - 1; try { @@ -838,7 +838,7 @@ public String read_string() { public String read_wstring() { checkChunk(); try { - switch (giopVersion_) { + switch (giopVersion) { case GIOP1_0: case GIOP1_1: return read_wstring_pre_1_2(); @@ -862,8 +862,8 @@ private String read_wstring_pre_1_2() { // in GIOP 1.0/1.1, there is no BOM - use the endianness from context char[] tmp = new char[numChars]; - final WcharCodec wcharCodec = codeConverters_.wcharCodec; - for (int i = 0; i < numChars; i++) tmp[i] = wcharCodec.readCharWithEndianFlag(readBuffer, swap_); + final WcharCodec wcharCodec = codecs.wcharCodec; + for (int i = 0; i < numChars; i++) tmp[i] = wcharCodec.readCharWithEndianFlag(readBuffer, swapBytes); // Check for terminating null wchar if (0 != tmp[numChars - 1]) throw newMarshalError(MinorReadWStringNoTerminator); @@ -882,7 +882,7 @@ private String read_wstring_1_2() { final int endPosition = readBuffer.getPosition() + numOctets; // this method checks for and consumes a BOM if present, returning the appropriately endian char reader - CharReader reader = codeConverters_.wcharCodec.beginToReadString(readBuffer); + CharReader reader = codecs.wcharCodec.beginToReadString(readBuffer); while (readBuffer.getPosition() < endPosition) builder.append(reader.readChar(readBuffer)); @@ -920,7 +920,7 @@ public void read_short_array(short[] value, int offset, int length) { readBuffer.align(TWO_BYTE_BOUNDARY); if (readBuffer.available() < length * 2) throw newMarshalError(MinorReadShortArrayOverflow); - range(offset, offset + length).forEach(swap_ ? + range(offset, offset + length).forEach(swapBytes ? i -> value[i] = readBuffer.readShort_LE() : i -> value[i] = readBuffer.readShort()); } @@ -941,7 +941,7 @@ public void read_long_array(int[] value, int offset, int length) { if (readBuffer.available() < length * 4) throw newMarshalError(MinorReadLongArrayOverflow); - range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swapBytes ? i -> value[i] = readBuffer.readInt_LE() : i -> value[i] = readBuffer.readInt()); } @@ -967,7 +967,7 @@ public void read_longlong_array(long[] value, int offset, int length) { checkChunk(); readBuffer.align(EIGHT_BYTE_BOUNDARY); if (readBuffer.available() < length * 8) throw newMarshalError(MinorReadLongLongArrayOverflow); - range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swapBytes ? i -> value[i] = readBuffer.readLong_LE() : i -> value[i] = readBuffer.readLong()); } @@ -985,7 +985,7 @@ public void read_float_array(float[] value, int offset, int length) { checkChunk(); readBuffer.align(FOUR_BYTE_BOUNDARY); if (readBuffer.available() < length * 4) throw newMarshalError(MinorReadFloatArrayOverflow); - range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swapBytes ? i -> value[i] = readBuffer.readFloat_LE() : i -> value[i] = readBuffer.readFloat()); } @@ -995,7 +995,7 @@ public void read_double_array(double[] value, int offset, int length) { checkChunk(); readBuffer.align(EIGHT_BYTE_BOUNDARY); if (readBuffer.available() < length * 8) throw newMarshalError(MinorReadDoubleArrayOverflow); - range(offset, offset + length).forEach( swap_ ? + range(offset, offset + length).forEach( swapBytes ? i -> value[i] = readBuffer.readDouble_LE() : i -> value[i] = readBuffer.readDouble()); } @@ -1004,8 +1004,8 @@ public org.omg.CORBA.Object read_Object() { checkChunk(); IOR ior = IORHelper.read(this); if ((ior.type_id.isEmpty()) && (ior.profiles.length == 0)) return null; - if (orbInstance_ == null) throw new INITIALIZE("InputStream must be created " + "by a full ORB"); - ObjectFactory objectFactory = orbInstance_.getObjectFactory(); + if (orbInstance == null) throw new INITIALIZE("InputStream must be created by a full ORB"); + ObjectFactory objectFactory = orbInstance.getObjectFactory(); return objectFactory.createObject(ior); } @@ -1099,8 +1099,8 @@ public TypeCode read_TypeCode() { return readTypeCodeImpl(new Hashtable<>(), true); } - public org.omg.CORBA.Any read_any() { - org.omg.CORBA.Any any = new AnyImpl(orbInstance_); + public Any read_any() { + Any any = new AnyImpl(orbInstance); any.read_value(this, read_TypeCode()); return any; } @@ -1109,7 +1109,7 @@ public org.omg.CORBA.Context read_Context() { final int len = read_ulong(); String[] values = new String[len]; for (int i = 0; i < len; i++) values[i] = read_string(); - return new Context(orbInstance_.getORB(), "", values); + return new Context(orbInstance.getORB(), "", values); } public Principal read_Principal() { @@ -1190,16 +1190,16 @@ public Object read_abstract_interface(@SuppressWarnings("rawtypes") Class clz) { return valueReader().readAbstractInterface(clz); } - public void read_value(org.omg.CORBA.Any any, TypeCode tc) { + public void read_value(Any any, TypeCode tc) { valueReader().readValueAny(any, tc); } - private YokoInputStream(ReadBuffer readBuffer, int offs, boolean swap, CodeConverters codeConverters, GiopVersion giopVersion) { + private YokoInputStream(ReadBuffer readBuffer, int offs, boolean swapBytes, CodecPair codecs, GiopVersion giopVersion) { this.readBuffer = readBuffer.setPosition(offs); - this.swap_ = swap; - this.origPos_ = offs; - this.origSwap_ = swap; - _OB_codeConverters(codeConverters, giopVersion); + this.swapBytes = swapBytes; + this.origPos = offs; + this.origSwap = swapBytes; + setCodecsAndGiopVersion(codecs, giopVersion); } /** @@ -1207,24 +1207,24 @@ private YokoInputStream(ReadBuffer readBuffer, int offs, boolean swap, CodeConve */ @SuppressWarnings("CopyConstructorMissesField") public YokoInputStream(YokoInputStream that) { - this(that.readBuffer.clone(), that.origPos_, that.origSwap_, that.codeConverters_, that.giopVersion_); - this.orbInstance_ = that.orbInstance_; + this(that.readBuffer.clone(), that.origPos, that.origSwap, that.codecs, that.giopVersion); + this.orbInstance = that.orbInstance; } - public YokoInputStream(ReadBuffer readBuffer, boolean swap, CodeConverters codeConverters, GiopVersion giopVersion) { - this(readBuffer, 0, swap, codeConverters, giopVersion); + public YokoInputStream(ReadBuffer readBuffer, boolean swapBytes, CodecPair codecs, GiopVersion giopVersion) { + this(readBuffer, 0, swapBytes, codecs, giopVersion); } - public YokoInputStream(byte[] data, boolean swap, CodeConverters codeConverters, GiopVersion giopVersion) { - this(Buffer.createReadBuffer(data), swap, codeConverters, giopVersion); + public YokoInputStream(byte[] data, boolean swapBytes, CodecPair codecs, GiopVersion giopVersion) { + this(Buffer.createReadBuffer(data), swapBytes, codecs, giopVersion); } - public YokoInputStream(ReadBuffer readBuffer, int offs, boolean swap) { - this(readBuffer, offs, swap, null, null); + public YokoInputStream(ReadBuffer readBuffer, int offs, boolean swapBytes) { + this(readBuffer, offs, swapBytes, null, null); } - public YokoInputStream(ReadBuffer readBuffer, boolean swap) { - this(readBuffer, swap, null, null); + public YokoInputStream(ReadBuffer readBuffer, boolean swapBytes) { + this(readBuffer, swapBytes, null, null); } public YokoInputStream(ReadBuffer readBuffer) { @@ -1235,13 +1235,13 @@ public YokoInputStream(byte[] data) { this(Buffer.createReadBuffer(data)); } - public void _OB_codeConverters(CodeConverters converters, GiopVersion giopVersion) { - if (giopVersion != null) giopVersion_ = giopVersion; - codeConverters_ = CodeConverters.createCopy(converters); + public void setCodecsAndGiopVersion(CodecPair codecs, GiopVersion giopVersion) { + if (giopVersion != null) this.giopVersion = giopVersion; + this.codecs = CodecPair.createCopy(codecs); } - public CodeConverters _OB_codeConverters() { - return codeConverters_; + public CodecPair getCodecs() { + return codecs; } public ReadBuffer getBuffer() { @@ -1257,12 +1257,12 @@ public void setPosition(int pos) { } public void _OB_swap(boolean swap) { - swap_ = swap; + this.swapBytes = swap; } public void _OB_reset() { - swap_ = origSwap_; - readBuffer.setPosition(origPos_); + swapBytes = origSwap; + readBuffer.setPosition(origPos); } public void _OB_skip(int n) { @@ -1278,24 +1278,24 @@ public void skipAlign(AlignmentBoundary boundary) { } public void _OB_readEndian() { - swap_ = read_boolean(); // false means big endian + swapBytes = read_boolean(); // false means big endian } public void _OB_ORBInstance(ORBInstance orbInstance) { - orbInstance_ = orbInstance; + this.orbInstance = orbInstance; - if (orbInstance_ != null && orbInstance_.useTypeCodeCache()) { - cache_ = TypeCodeCache.instance(); + if (this.orbInstance != null && this.orbInstance.useTypeCodeCache()) { + cache = TypeCodeCache.instance(); } } - public ORBInstance _OB_ORBInstance() { return orbInstance_; } + public ORBInstance _OB_ORBInstance() { return orbInstance; } public int _OB_readLongUnchecked() { // The chunking code needs to read a long value without entering an infinite loop readBuffer.align(FOUR_BYTE_BOUNDARY); try { - return swap_ ? readBuffer.readInt_LE() : readBuffer.readInt(); + return swapBytes ? readBuffer.readInt_LE() : readBuffer.readInt(); } catch (IndexOutOfBoundsException e) { throw newMarshalError((MinorReadLongOverflow), e); } @@ -1315,19 +1315,19 @@ public void __setSendingContextRuntime(CodeBase runtime) { * to a com.sun.org.omg.SendingContext.CodeBase. Narrowing CodeBaseProxy * is not possible, we need a stub. */ - sendingContextRuntime_ = (runtime instanceof CodeBaseProxy) ? ((CodeBaseProxy) runtime).getCodeBase() : runtime; + sendingContextRuntime = (runtime instanceof CodeBaseProxy) ? ((CodeBaseProxy) runtime).getCodeBase() : runtime; } public CodeBase __getSendingContextRuntime() { - return sendingContextRuntime_; + return sendingContextRuntime; } public void __setCodeBase(String codebase) { - this.codebase_ = codebase; + this.codebase = codebase; } public String __getCodeBase() { - return codebase_; + return codebase; } /** @@ -1359,8 +1359,8 @@ public String dumpRemainingData() { public StringBuilder dumpAllDataWithPosition(StringBuilder sb, String label) { return readBuffer.dumpAllDataWithPosition(sb, label); } private void checkChunk() { - if (valueReader_ != null) { - valueReader_.checkChunk(); + if (valueReader != null) { + valueReader.checkChunk(); } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java index 406e242ea..a2706f88b 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java @@ -24,13 +24,14 @@ import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.SimplyCloseable; import org.apache.yoko.io.WriteBuffer; -import org.apache.yoko.orb.OB.CodeConverters; +import org.apache.yoko.orb.OB.CodecPair; import org.apache.yoko.orb.OB.ORBInstance; import org.apache.yoko.orb.OB.TypeCodeFactory; import org.apache.yoko.orb.OB.ValueWriter; import org.apache.yoko.orb.OCI.GiopVersion; import org.apache.yoko.util.Assert; import org.apache.yoko.util.Timeout; +import org.omg.CORBA.Any; import org.omg.CORBA.BAD_TYPECODE; import org.omg.CORBA.LocalObject; import org.omg.CORBA.MARSHAL; @@ -109,21 +110,21 @@ public final class YokoOutputStream extends OutputStream implements ValueOutputStream { private static final Logger LOGGER = Logger.getLogger(YokoOutputStream.class.getName()); - private ORBInstance orbInstance_; + private ORBInstance orbInstance; private final WriteBuffer writeBuffer; - private final GiopVersion giopVersion_; - private final CodeConverters codeConverters_; + private final GiopVersion giopVersion; + private final CodecPair codecs; // Handles all OBV marshalling - private ValueWriter valueWriter_; + private ValueWriter valueWriter; // In GIOP 1.2, the body must be aligned on an 8-byte boundary. // This flag is used to keep track of when that alignment is necessary. private boolean atEndOfGiop_1_2_Header = false; - private Object invocationContext_; + private Object invocationContext; - private Object delegateContext_; + private Object delegateContext; private Timeout timeout = Timeout.NEVER; private SimplyCloseable recordLength() { @@ -374,7 +375,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { } private ValueWriter valueWriter() { - return null == valueWriter_ ? (valueWriter_ = new ValueWriter(this, writeBuffer)) : valueWriter_; + return null == valueWriter ? (valueWriter = new ValueWriter(this, writeBuffer)) : valueWriter; } private void addCapacity(int size) { @@ -384,7 +385,7 @@ private void addCapacity(int size) { return; } // If a new chunk is required, there will be a recursive call to addCapacity(). - if (writeBuffer.isComplete() && valueWriter_ != null) valueWriter_.checkBeginChunk(); + if (writeBuffer.isComplete() && valueWriter != null) valueWriter.checkBeginChunk(); // If there isn't enough room, then reallocate the buffer final boolean resized = writeBuffer.ensureAvailable(size); @@ -403,7 +404,7 @@ private void addCapacity(int size, AlignmentBoundary boundary) { Assert.ensure(boundary != NO_BOUNDARY); // If a new chunk is required, there will be a recursive call to addCapacity(). - if (writeBuffer.isComplete() && valueWriter_ != null) valueWriter_.checkBeginChunk(); + if (writeBuffer.isComplete() && valueWriter != null) valueWriter.checkBeginChunk(); if (atEndOfGiop_1_2_Header) { boundary = EIGHT_BYTE_BOUNDARY; @@ -421,12 +422,12 @@ public void write(int b) { write_long(b); } - public org.omg.CORBA.ORB orb() { return (orbInstance_ == null) ? null : orbInstance_.getORB(); } + public org.omg.CORBA.ORB orb() { return (orbInstance == null) ? null : orbInstance.getORB(); } @Override public YokoInputStream create_input_stream() { - YokoInputStream in = new YokoInputStream(getBufferReader(), false, codeConverters_, giopVersion_); - in._OB_ORBInstance(orbInstance_); + YokoInputStream in = new YokoInputStream(getBufferReader(), false, codecs, giopVersion); + in._OB_ORBInstance(orbInstance); return in; } @@ -436,15 +437,15 @@ public void write_boolean(boolean value) { } public void write_char(char value) { - final CharCodec codec = codeConverters_.charCodec; + final CharCodec codec = codecs.charCodec; addCapacity(codec.octetCount(value)); codec.writeChar(value, writeBuffer); } public void write_wchar(char value) { - final WcharCodec codec = codeConverters_.wcharCodec; + final WcharCodec codec = codecs.wcharCodec; - switch (giopVersion_) { + switch (giopVersion) { case GIOP1_0: case GIOP1_1: // add aligned space for 1 character @@ -499,7 +500,7 @@ public void write_double(double value) { public void write_string(String value) { LOGGER.finest("Writing string value " + value); - final CharCodec codec = codeConverters_.charCodec; + final CharCodec codec = codecs.charCodec; final char[] arr = value.toCharArray(); if (codec.isFixedWidth()) { @@ -529,7 +530,7 @@ public void write_string(String value) { public void write_wstring(String value) { if (LOGGER.isLoggable(FINEST)) LOGGER.finest("Writing wstring value " + value); - switch (giopVersion_) { + switch (giopVersion) { case GIOP1_0: case GIOP1_1: write_wstring_pre_1_2(value); @@ -544,7 +545,7 @@ private void write_wstring_pre_1_2(String value) { write_ulong(value.length() + 1); // already 4-byte aligned, so just add the needed capacity for len 2-byte chars addCapacity(2*(value.length() + 1)); - final WcharCodec codec = codeConverters_.wcharCodec; + final WcharCodec codec = codecs.wcharCodec; // now write all the characters for (int i = 0; i < value.length(); i++) codec.writeChar(value.charAt(i), writeBuffer); // and the null terminator @@ -559,7 +560,7 @@ private void write_wstring_1_2(String value) { return; } // now we know there is a first character - final WcharCodec codec = codeConverters_.wcharCodec; + final WcharCodec codec = codecs.wcharCodec; int numOctets = codec.octetCount(value); // write the length of the string in octets write_ulong(numOctets); @@ -688,7 +689,7 @@ public void write_TypeCode(TypeCode t) { writeTypeCodeImpl(t, new HashMap()); } - public void write_any(org.omg.CORBA.Any value) { + public void write_any(Any value) { LOGGER.finest("Writing an ANY value of type " + value.type().kind()); write_TypeCode(value.type()); value.write_value(this); @@ -931,7 +932,7 @@ private void copyAbstractInterfaceFrom(org.omg.CORBA.portable.InputStream in) { } private void copyArrayFrom(org.omg.CORBA.portable.InputStream in, TypeCode tc) throws BadKind { - final boolean swapInput = (in instanceof YokoInputStream) && ((YokoInputStream)in).swap_; + final boolean swapInput = (in instanceof YokoInputStream) && ((YokoInputStream)in).swapBytes; int len; if (tc.kind().value() == _tk_sequence) { @@ -1286,22 +1287,22 @@ public YokoOutputStream(int initialBufferSize) { this(Buffer.createWriteBuffer(initialBufferSize), null, null); } - public YokoOutputStream(CodeConverters converters, GiopVersion giopVersion) { - this(Buffer.createWriteBuffer(), converters, giopVersion); + public YokoOutputStream(CodecPair codecs, GiopVersion giopVersion) { + this(Buffer.createWriteBuffer(), codecs, giopVersion); } - public YokoOutputStream(int initialBufferSize, CodeConverters converters, GiopVersion giopVersion) { - this(Buffer.createWriteBuffer(initialBufferSize), converters, giopVersion); + public YokoOutputStream(int initialBufferSize, CodecPair codecs, GiopVersion giopVersion) { + this(Buffer.createWriteBuffer(initialBufferSize), codecs, giopVersion); } public YokoOutputStream(WriteBuffer writeBuffer) { this(writeBuffer, null, null); } - public YokoOutputStream(WriteBuffer writeBuffer, CodeConverters converters, GiopVersion giopVersion) { + public YokoOutputStream(WriteBuffer writeBuffer, CodecPair codecs, GiopVersion giopVersion) { this.writeBuffer = writeBuffer; - this.giopVersion_ = giopVersion == null ? GIOP1_0 : giopVersion; - this.codeConverters_ = CodeConverters.createCopy(converters); + this.giopVersion = giopVersion == null ? GIOP1_0 : giopVersion; + this.codecs = CodecPair.createCopy(codecs); } @Override @@ -1348,23 +1349,23 @@ public void _OB_endValue() { } public void _OB_ORBInstance(ORBInstance orbInstance) { - orbInstance_ = orbInstance; + this.orbInstance = orbInstance; } public void _OB_invocationContext(Object invocationContext) { - invocationContext_ = invocationContext; + this.invocationContext = invocationContext; } public Object _OB_invocationContext() { - return invocationContext_; + return invocationContext; } void _OB_delegateContext(Object delegateContext) { - delegateContext_ = delegateContext; + this.delegateContext = delegateContext; } Object _OB_delegateContext() { - return delegateContext_; + return delegateContext; } @Override diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CharMapInfo.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CharMapInfo.java deleted file mode 100644 index c8f9eb82b..000000000 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CharMapInfo.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2022 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -enum CharMapInfo { - CM_8859_2("ISO 8859-2:1999 to Unicode", CharSequences.CS_8859_2), - CM_8859_3("ISO/IEC 8859-3:1999 to Unicode", CharSequences.CS_8859_3), - CM_8859_4("ISO/IEC 8859-4:1998 to Unicode", CharSequences.CS_8859_4), - CM_8859_5("ISO 8859-5:1999 to Unicode", CharSequences.CS_8859_5), - CM_8859_7("ISO 8859-7:1987 to Unicode", CharSequences.CS_8859_7), - CM_8859_9("ISO/IEC 8859-9:1999 to Unicode", CharSequences.CS_8859_9), - CM_IDENTITY("NO conversion required") { - public char convertFromJava(char v) { return v; } - public char convertToJava(char v) { return v; } - } - ; - - private static enum CharSequences { - ; - - private static final char[] CS_8859_2 = { - 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, - 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, - 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, - 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, - 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, - 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, - 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, - 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, - 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, - 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, - 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, - 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 - }; - private static final char[] CS_8859_3 = { - 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, - 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, - 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, - 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, - 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, - 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, - 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, - 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, - 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 - }; - private static final char[] CS_8859_4 = { - 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, - 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, - 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, - 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, - 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, - 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, - 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, - 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, - 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, - 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, - 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9 - }; - private static final char[] CS_8859_5 = { - 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, - 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, - 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, - 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, - 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, - 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, - 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, - 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, - 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, - 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, - 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, - 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F - }; - private static final char[] CS_8859_7 = { - 0x00A0, 0x2018, 0x2019, 0x00A3, 0x0000, 0x0000, 0x00A6, 0x00A7, - 0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x0000, 0x2015, - 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, - 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, - 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, - 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, /* - */ - }; - private static final char[] CS_8859_9 = { - /* --------------------------------------------------*/ 0x00CF, - 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, - 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, - 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, - 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, /* - */ - }; - } - - private final char[] mapping; - - /** - * @param mapping A subsequence of java characters from the named char set: - * the first element is an anchor, and represents a - * codepoint unchanged by this mapping. This first element - * is therefore also the offset between the index and the - * represented codepoint.
- * For a given int codepoint the mapping from - * the named char set to Java is given by:
- * int offset = mapping[0];
- * char javaChar = mapping[codepoint - offset]; - */ - private CharMapInfo(String desc, char[] mapping) { - this.mapping = mapping; - } - - private CharMapInfo(String name) { - this(name, null); - } - - public char convertToJava(char v) { - final int offset = mapping[0]; - if (v < offset) return v; - int i = v - offset; - if (i >= mapping.length) return v; - return (char) mapping[i]; - } - - public char convertFromJava(char v) { - final int offset = mapping[0]; - if (v < offset) return v; - for (int i = 0; i < mapping.length; i++) { - if (mapping[i] == v) - return (char) (i + offset); - } - return v; - } -} diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Client.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Client.java index c40175ad2..949a7fb5f 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Client.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Client.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,11 +34,11 @@ public abstract class Client { public static final int Threaded = 2; private final String label = ObjectUtil.getNextObjectLabel(this.getClass()); private final AtomicInteger users = new AtomicInteger(0); - private final CodeConverters codeConverters; + private final CodecPair codecs; final int concurrencyModel; - Client(int concModel, CodeConverters conv) { - codeConverters = conv; + Client(int concModel, CodecPair codecs) { + this.codecs = codecs; concurrencyModel = concModel; } @@ -61,8 +61,8 @@ public final boolean release() { return count == 0; } - final CodeConverters codeConverters() { - return codeConverters; + final CodecPair codecs() { + return codecs; } public abstract int getNewRequestID(); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java index 7ad10bd0f..6af66dc2e 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -279,9 +279,9 @@ public synchronized Vector getClientProfilePairs(IOR ior, Pol // have. // for (ProfileInfo profileInfo: profileInfos) { - CodeConverters conv = CodeSetUtil.getCodeConverters(orbInstance, profileInfo); + CodecPair codecs = CodeSetUtil.getNegotiatedCodecs(orbInstance, profileInfo); - Client newClient = new GIOPClient(orbInstance, connector, concModel_, conv, enableBidir); + Client newClient = new GIOPClient(orbInstance, connector, concModel_, codecs, enableBidir); if (!pairs.isEmpty()) { boolean matched = false; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java index 2d507d190..087c34565 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,13 +25,6 @@ import static java.util.Collections.unmodifiableMap; import static java.util.EnumSet.complementOf; import static java.util.Objects.requireNonNull; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_2; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_3; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_4; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_5; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_7; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_9; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_IDENTITY; import static org.apache.yoko.orb.OB.CodeSetInfo.Charset.shareCommonCharset; import static org.apache.yoko.orb.OB.CodeSetInfo.Charset.x0001; import static org.apache.yoko.orb.OB.CodeSetInfo.Charset.x0011; @@ -56,199 +49,199 @@ import static org.apache.yoko.orb.OB.CodeSetInfo.Charset.x1000; public enum CodeSetInfo { - NONE("none", 0x00000000, 2), - ISO_LATIN_1("ISO 8859-1:1987; Latin Alphabet No. 1", 0x00010001, 1, CM_IDENTITY, x0011), - ISO_LATIN_2("ISO 8859-2:1987; Latin Alphabet No. 2", 0x00010002, 1, CM_8859_2, x0012), - ISO_LATIN_3("ISO 8859-3:1988; Latin Alphabet No. 3", 0x00010003, 1, CM_8859_3, x0013), - ISO_LATIN_4("ISO 8859-4:1988; Latin Alphabet No. 4", 0x00010004, 1, CM_8859_4, x0014), - ISO_8859_5("ISO/IEC 8859-5:1988; Latin-Cyrillic Alphabet", 0x00010005, 1, CM_8859_5, x0015), - ISO_8859_6("ISO 8859-6:1987; Latin-Arabic Alphabet", 0x00010006, 1, x0016), - ISO_8859_7("ISO 8859-7:1987; Latin-Greek Alphabet", 0x00010007, 1, CM_8859_7, x0017), - ISO_8859_8("ISO 8859-8:1988; Latin-Hebrew Alphabet", 0x00010008, 1, x0018), - ISO_8859_9("ISO/IEC 8859-9:1989; Latin Alphabet No. 5", 0x00010009, 1, CM_8859_9, x0019), - ISO_IEC_8859_10_1992("ISO/IEC 8859-10:1992; Latin Alphabet No. 6", 0x0001000a, 1, x001a), - ISO_IEC_8859_15_1999("ISO/IEC 8859-15:1999; Latin Alphabet No. 9", 0x0001000f, 1, x0011), - ISO_646_IRV("ISO 646:1991 IRV (International Reference Version)", 0x00010020, 1, CM_IDENTITY, x0001), - UCS_2("ISO/IEC 10646-1:1993; UCS-2, Level 1", 0x00010100, 2, CM_IDENTITY, x1000), - UCS2_L2("ISO/IEC 10646-1:1993; UCS-2, Level 2", 0x00010101, 2, x1000), - UCS2_L3("ISO/IEC 10646-1:1993; UCS-2, Level 3", 0x00010102, 2, x1000), - USC4_L1("ISO/IEC 10646-1:1993; UCS-4, Level 1", 0x00010104, 4, x1000), - USC4_L2("ISO/IEC 10646-1:1993; UCS-4, Level 2", 0x00010105, 4, x1000), - USC4_L3("ISO/IEC 10646-1:1993; UCS-4, Level 3", 0x00010106, 4, x1000), - UTF1("ISO/IEC 10646-1:1993; UTF-1, UCS Transformation Format 1", 0x00010108, 5, x1000), - UTF_16("ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form", 0x00010109, 2, CM_IDENTITY, x1000), - JIS_X0201_1976("JIS X0201:1976; Japanese phonetic characters", 0x00030001, 1, x0080), - JIS_X0208_1978("JIS X0208:1978 Japanese Kanji Graphic Characters", 0x00030004, 2, x0081), - JIS_X0208_1983("JIS X0208:1983 Japanese Kanji Graphic Characters", 0x00030005, 2, x0081), - JIS_X0208_1990("JIS X0208:1990 Japanese Kanji Graphic Characters", 0x00030006, 2, x0081), - JIS_X0212_1990("JIS X0212:1990; Supplementary Japanese Kanji Graphic Chars", 0x0003000a, 2, x0082), - JIS_eucJP_1993("JIS eucJP:1993; Japanese EUC", 0x00030010, 3, x0011, x0080, x0081, x0082), - KS_C5601_1987("KS C5601:1987; Korean Hangul and Hanja Graphic Characters", 0x00040001, 2, x0100), - KS_C5657_1991("KS C5657:1991; Supplementary Korean Graphic Characters", 0x00040002, 2, x0101), - KS_eucKR_1991("KS eucKR:1991; Korean EUC", 0x0004000a, 2, x0011, x0100, x0101), - CNS_11643_1986("CNS 11643:1986; Taiwanese Hanzi Graphic Characters", 0x00050001, 2, x0180), - CNS_11643_1992("CNS 11643:1992; Taiwanese Extended Hanzi Graphic Chars", 0x00050002, 4, x0181), - CNS_eucTW_1991("CNS eucTW:1991; Taiwanese EUC", 0x0005000a, 4, x0001, x0180), - CNS_eucTW_1993("CNS eucTW:1993; Taiwanese EUC", 0x00050010, 4, x0001, x0181), - TIS_620_2529("TIS 620-2529, Thai characters", 0x000b0001, 1, x0200), - TTB_CCDC_1984("TTB CCDC:1984; Chinese Code for Data Communications", 0x000d0001, 2, x0180), - OSF_Japanese_UJIS("OSF Japanese UJIS", 0x05000010, 2, x0001, x0080, x0081), - OSF_Japanese_SJIS_1("OSF Japanese SJIS-1", 0x05000011, 2, x0001, x0080, x0081), - OSF_Japanese_SJIS_2("OSF Japanese SJIS-2", 0x05000012, 2, x0001, x0080, x0081), - UTF_8("X/Open UTF-8; UCS Transformation Format 8 (UTF-8)", 0x05010001, 6, CM_IDENTITY, x1000), - JVC_eucJP("JVC_eucJP", 0x05020001, 3, x0001, x0080, x0081, x0082), - JVC_SJIS("JVC_SJIS", 0x05020002, 2, x0001, x0080, x0081), - DEC_Kanji("DEC Kanji", 0x10000001, 2, x0011, x0080, x0081), - Super_DEC_Kanji("Super DEC Kanji", 0x10000002, 3, x0011, x0080, x0081, x0082), - DEC_Shift_JIS("DEC Shift JIS", 0x10000003, 2, x0011, x0080, x0081), - HP_roman8("HP roman8; English and Western European languages", 0x10010001, 1, x0011), - HP_kana8("HP kana8; Japanese katakana (incl JIS X0201:1976)", 0x10010002, 1, x0080), - HP_arabic8("HP arabic8; Arabic", 0x10010003, 1, x0016), - HP_greek8("HP greek8; Greek", 0x10010004, 1, x0017), - HP_hebrew8("HP hebrew8; Hebrew", 0x10010005, 1, x0018), - HP_turkish8("HP turkish8; Turkish", 0x10010006, 1, x0013, x0019), - HP15CN("HP15CN; encoding method for Simplified Chinese", 0x10010007, 2, x0001, x0300), - HP_big5("HP big5; encoding method for Traditional Chinese", 0x10010008, 2, x0001, x0180), - HP_japanese15__sjis("HP japanese15 (sjis); Shift-JIS for mainframe (incl JIS X0208:1990)", 0x10010009, 2, x0001, x0080, x0081), - HP_sjishi("HP sjishi; Shift-JIS for HP user (incl JIS X0208:1990)", 0x1001000a, 2, x0001, x0080, x0081), - HP_sjispc("HP sjispc; Shift-JIS for PC (incl JIS X0208:1990)", 0x1001000b, 2, x0001, x0080, x0081), - HP_ujis("HP ujis; EUC (incl JIS X0208:1990)", 0x1001000c, 2, x0001, x0080, x0081), - IBM_037__CCSID_00037("IBM-037 (CCSID 00037); CECP for USA, Canada, NL, Ptgl, Brazil, Australia, NZ", 0x10020025, 1, x0011), - IBM_273__CCSID_00273("IBM-273 (CCSID 00273); CECP for Austria, Germany", 0x10020111, 1, x0011), - IBM_277__CCSID_00277("IBM-277 (CCSID 00277); CECP for Denmark, Norway", 0x10020115, 1, x0011), - IBM_278__CCSID_00278("IBM-278 (CCSID 00278); CECP for Finland, Sweden", 0x10020116, 1, x0011), - IBM_280__CCSID_00280("IBM-280 (CCSID 00280); CECP for Italy", 0x10020118, 1, x0011), - IBM_282__CCSID_00282("IBM-282 (CCSID 00282); CECP for Portugal", 0x1002011a, 1, x0011), - IBM_284__CCSID_00284("IBM-284 (CCSID 00284); CECP for Spain, Latin America (Spanish)", 0x1002011c, 1, x0011), - IBM_285__CCSID_00285("IBM-285 (CCSID 00285); CECP for United Kingdom", 0x1002011d, 1, x0011), - IBM_290__CCSID_00290("IBM-290 (CCSID 00290); Japanese Katakana Host Ext SBCS", 0x10020122, 1, x0080), - IBM_297__CCSID_00297("IBM-297 (CCSID 00297); CECP for France", 0x10020129, 1, x0011), - IBM_300__CCSID_00300("IBM-300 (CCSID 00300); Japanese Host DBCS incl 4370 UDC", 0x1002012c, 2, x0081), - IBM_301__CCSID_00301("IBM-301 (CCSID 00301); Japanese PC Data DBCS incl 1880 UDC", 0x1002012d, 2, x0081), - IBM_420__CCSID_00420("IBM-420 (CCSID 00420); Arabic (presentation shapes)", 0x100201a4, 1, x0016), - IBM_424__CCSID_00424("IBM-424 (CCSID 00424); Hebrew", 0x100201a8, 1, x0018), - IBM_437__CCSID_00437("IBM-437 (CCSID 00437); PC USA", 0x100201b5, 1, x0011), - IBM_500__CCSID_00500("IBM-500 (CCSID 00500); CECP for Belgium, Switzerland", 0x100201f4, 1, x0011), - IBM_833__CCSID_00833("IBM-833 (CCSID 00833); Korean Host Extended SBCS", 0x10020341, 1, x0001), - IBM_834__CCSID_00834("IBM-834 (CCSID 00834); Korean Host DBCS incl 1227 UDC", 0x10020342, 2, x0100), - IBM_835__CCSID_00835("IBM-835 (CCSID 00835); T-Ch Host DBCS incl 6204 UDC", 0x10020343, 2, x0180), - IBM_836__CCSID_00836("IBM-836 (CCSID 00836); S-Ch Host Extended SBCS", 0x10020344, 1, x0001), - IBM_837__CCSID_00837("IBM-837 (CCSID 00837); S-Ch Host DBCS incl 1880 UDC", 0x10020345, 2, x0300), - IBM_838__CCSID_00838("IBM-838 (CCSID 00838); Thai Host Extended SBCS", 0x10020346, 1, x0200), - IBM_839__CCSID_00839("IBM-839 (CCSID 00839); Thai Host DBCS incl 374 UDC", 0x10020347, 2, x0200), - IBM_850__CCSID_00850("IBM-850 (CCSID 00850); Multilingual IBM PC Data-MLP 222", 0x10020352, 1, x0011), - IBM_852__CCSID_00852("IBM-852 (CCSID 00852); Multilingual Latin-2", 0x10020354, 1, x0012), - IBM_855__CCSID_00855("IBM-855 (CCSID 00855); Cyrillic PC Data", 0x10020357, 1, x0015), - IBM_856__CCSID_00856("IBM-856 (CCSID 00856); Hebrew PC Data (extensions)", 0x10020358, 1, x0018), - IBM_857__CCSID_00857("IBM-857 (CCSID 00857); Turkish Latin-5 PC Data", 0x10020359, 1, x0019), - IBM_861__CCSID_00861("IBM-861 (CCSID 00861); PC Data Iceland", 0x1002035d, 1, x0011), - IBM_862__CCSID_00862("IBM-862 (CCSID 00862); PC Data Hebrew", 0x1002035e, 1, x0018), - IBM_863__CCSID_00863("IBM-863 (CCSID 00863); PC Data Canadian French", 0x1002035f, 1, x0011), - IBM_864__CCSID_00864("IBM-864 (CCSID 00864); Arabic PC Data", 0x10020360, 1, x0016), - IBM_866__CCSID_00866("IBM-866 (CCSID 00866); PC Data Cyrillic 2", 0x10020362, 1, x0015), - IBM_868__CCSID_00868("IBM-868 (CCSID 00868); Urdu PC Data", 0x10020364, 1, x0016), - IBM_869__CCSID_00869("IBM-869 (CCSID 00869); Greek PC Data", 0x10020365, 1, x0017), - IBM_870__CCSID_00870("IBM-870 (CCSID 00870); Multilingual Latin-2 EBCDIC", 0x10020366, 1, x0012), - IBM_871__CCSID_00871("IBM-871 (CCSID 00871); CECP for Iceland", 0x10020367, 1, x0011), - IBM_874__CCSID_00874("IBM-874 (CCSID 00874); Thai PC Display Extended SBCS", 0x1002036a, 1, x0200), - IBM_875__CCSID_00875("IBM-875 (CCSID 00875); Greek", 0x1002036b, 1, x0017), - IBM_880__CCSID_00880("IBM-880 (CCSID 00880); Multilingual Cyrillic", 0x10020370, 1, x0015), - IBM_891__CCSID_00891("IBM-891 (CCSID 00891); Korean PC Data SBCS", 0x1002037b, 1, x0001), - IBM_896__CCSID_00896("IBM-896 (CCSID 00896); Japanese Katakana characters; superset of JIS X0201:1976", 0x10020380, 1, x0080), - IBM_897__CCSID_00897("IBM-897 (CCSID 00897); PC Data Japanese SBCS (use with CP 00301)", 0x10020381, 1, x0080), - IBM_903__CCSID_00903("IBM-903 (CCSID 00903); PC Data Simplified Chinese SBCS (use with DBCS)", 0x10020387, 1, x0001), - IBM_904__CCSID_00904("IBM-904 (CCSID 00904); PC Data Traditional Chinese SBCS (use with DBCS)", 0x10020388, 1, x0001), - IBM_918__CCSID_00918("IBM-918 (CCSID 00918); Urdu", 0x10020396, 1, x0016), - IBM_921__CCSID_00921("IBM-921 (CCSID 00921); Baltic 8-Bit", 0x10020399, 1, x001a), - IBM_922__CCSID_00922("IBM-922 (CCSID 00922); Estonia 8-Bit", 0x1002039a, 1, x001a), - IBM_926__CCSID_00926("IBM-926 (CCSID 00926); Korean PC Data DBCS incl 1880 UDC", 0x1002039e, 2, x0100), - IBM_927__CCSID_00927("IBM-927 (CCSID 00927); T-Ch PC Data DBCS incl 6204 UDC", 0x1002039f, 2, x0180), - IBM_928__CCSID_00928("IBM-928 (CCSID 00928); S-Ch PC Data DBCS incl 1880 UDC", 0x100203a0, 2, x0300), - IBM_929__CCSID_00929("IBM-929 (CCSID 00929); Thai PC Data DBCS incl 374 UDC", 0x100203a1, 2, x0200), - IBM_930__CCSID_00930("IBM-930 (CCSID 00930); Kat-Kanji Host MBCS Ext-SBCS", 0x100203a2, 2, x0080, x0081), - IBM_932__CCSID_00932("IBM-932 (CCSID 00932); Japanese PC Data Mixed", 0x100203a4, 2, x0080, x0081), - IBM_933__CCSID_00933("IBM-933 (CCSID 00933); Korean Host Extended SBCS", 0x100203a5, 2, x0001, x0100), - IBM_934__CCSID_00934("IBM-934 (CCSID 00934); Korean PC Data Mixed", 0x100203a6, 2, x0001, x0100), - IBM_935__CCSID_00935("IBM-935 (CCSID 00935); S-Ch Host Mixed", 0x100203a7, 2, x0001, x0300), - IBM_936__CCSID_00936("IBM-936 (CCSID 00936); PC Data S-Ch MBCS", 0x100203a8, 2, x0001, x0300), - IBM_937__CCSID_00937("IBM-937 (CCSID 00937); T-Ch Host Mixed", 0x100203a9, 2, x0001, x0180), - IBM_938__CCSID_00938("IBM-938 (CCSID 00938); PC Data T-Ch MBCS", 0x100203aa, 2, x0001, x0180), - IBM_939__CCSID_00939("IBM-939 (CCSID 00939); Latin-Kanji Host MBCS", 0x100203ab, 2, x0080, x0081), - IBM_941__CCSID_00941("IBM-941 (CCSID 00941); Japanese PC DBCS for Open", 0x100203ad, 2, x0081), - IBM_942__CCSID_00942("IBM-942 (CCSID 00942); Japanese PC Data Mixed", 0x100203ae, 2, x0080, x0081), - IBM_943__CCSID_00943("IBM-943 (CCSID 00943); Japanese PC MBCS for Open", 0x100203af, 2, x0080, x0081), - IBM_946__CCSID_00946("IBM-946 (CCSID 00946); S-Ch PC Data Mixed", 0x100203b2, 2, x0001, x0300), - IBM_947__CCSID_00947("IBM-947 (CCSID 00947); T-Ch PC Data DBCS incl 6204 UDC", 0x100203b3, 2, x0180), - IBM_948__CCSID_00948("IBM-948 (CCSID 00948); T-Ch PC Data Mixed", 0x100203b4, 2, x0001, x0180), - IBM_949__CCSID_00949("IBM-949 (CCSID 00949); IBM KS PC Data Mixed", 0x100203b5, 2, x0001, x0100), - IBM_950__CCSID_00950("IBM-950 (CCSID 00950); T-Ch PC Data Mixed", 0x100203b6, 2, x0001, x0180), - IBM_951__CCSID_00951("IBM-951 (CCSID 00951); IBM KS PC Data DBCS incl 1880 UDC", 0x100203b7, 2, x0100), - IBM_955__CCSID_00955("IBM-955 (CCSID 00955); Japan Kanji characters; superset of JIS X0208:1978", 0x100203bb, 2, x0081), - IBM_964__CCSID_00964("IBM-964 (CCSID 00964); T-Chinese EUC CNS1163 plane 1,2", 0x100203c4, 4, x0001, x0180), - IBM_970__CCSID_00970("IBM-970 (CCSID 00970); Korean EUC", 0x100203ca, 2, x0011, x0100, x0101), - IBM_1006__CCSID_01006("IBM-1006 (CCSID 01006); Urdu 8-bit", 0x100203ee, 1, x0016), - IBM_1025__CCSID_01025("IBM-1025 (CCSID 01025); Cyrillic Multilingual", 0x10020401, 1, x0015), - IBM_1026__CCSID_01026("IBM-1026 (CCSID 01026); Turkish Latin-5", 0x10020402, 1, x0019), - IBM_1027__CCSID_01027("IBM-1027 (CCSID 01027); Japanese Latin Host Ext SBCS", 0x10020403, 1, x0080), - IBM_1040__CCSID_01040("IBM-1040 (CCSID 01040); Korean PC Data Extended SBCS", 0x10020410, 1, x0001), - IBM_1041__CCSID_01041("IBM-1041 (CCSID 01041); Japanese PC Data Extended SBCS", 0x10020411, 1, x0080), - IBM_1043__CCSID_01043("IBM-1043 (CCSID 01043); T-Ch PC Data Extended SBCS", 0x10020413, 1, x0001), - IBM_1046__CCSID_01046("IBM-1046 (CCSID 01046); Arabic PC Data", 0x10020416, 1, x0016), - IBM_1047__CCSID_01047("IBM-1047 (CCSID 01047); Latin-1 Open System", 0x10020417, 1, x0011), - IBM_1088__CCSID_01088("IBM-1088 (CCSID 01088); IBM KS Code PC Data SBCS", 0x10020440, 1, x0001), - IBM_1097__CCSID_01097("IBM-1097 (CCSID 01097); Farsi", 0x10020449, 1, x0016), - IBM_1098__CCSID_01098("IBM-1098 (CCSID 01098); Farsi PC Data", 0x1002044a, 1, x0016), - IBM_1112__CCSID_01112("IBM-1112 (CCSID 01112); Baltic Multilingual", 0x10020458, 1, x001a), - IBM_1114__CCSID_01114("IBM-1114 (CCSID 01114); T-Ch PC Data SBCS (IBM BIG-5)", 0x1002045a, 1, x0001), - IBM_1115__CCSID_01115("IBM-1115 (CCSID 01115); S-Ch PC Data SBCS (IBM GB)", 0x1002045b, 1, x0001), - IBM_1122__CCSID_01122("IBM-1122 (CCSID 01122); Estonia", 0x10020462, 1, x001a), - IBM_1250__CCSID_01250("IBM-1250 (CCSID 01250); MS Windows Latin-2", 0x100204e2, 1, x0012), - IBM_1251__CCSID_01251("IBM-1251 (CCSID 01251); MS Windows Cyrillic", 0x100204e3, 1, x0015), - IBM_1252__CCSID_01252("IBM-1252 (CCSID 01252); MS Windows Latin-1", 0x100204e4, 1, x0011), - IBM_1253__CCSID_01253("IBM-1253 (CCSID 01253); MS Windows Greek", 0x100204e5, 1, x0017), - IBM_1254__CCSID_01254("IBM-1254 (CCSID 01254); MS Windows Turkey", 0x100204e6, 1, x0019), - IBM_1255__CCSID_01255("IBM-1255 (CCSID 01255); MS Windows Hebrew", 0x100204e7, 1, x0018), - IBM_1256__CCSID_01256("IBM-1256 (CCSID 01256); MS Windows Arabic", 0x100204e8, 1, x0016), - IBM_1257__CCSID_01257("IBM-1257 (CCSID 01257); MS Windows Baltic", 0x100204e9, 1, x001a), - IBM_1380__CCSID_01380("IBM-1380 (CCSID 01380); S-Ch PC Data DBCS incl 1880 UDC", 0x10020564, 2, x0300), - IBM_1381__CCSID_01381("IBM-1381 (CCSID 01381); S-Ch PC Data Mixed incl 1880 UDC", 0x10020565, 2, x0001, x0300), - IBM_1383__CCSID_01383("IBM-1383 (CCSID 01383); S-Ch EUC GB 2312-80 set (1382)", 0x10020567, 3, x0001, x0300), - IBM_300__CCSID_04396("IBM-300 (CCSID 04396); Japanese Host DBCS incl 1880 UDC", 0x1002112c, 2, x0081), - IBM_850__CCSID_04946("IBM-850 (CCSID 04946); Multilingual IBM PC Data-190", 0x10021352, 1, x0011), - IBM_852__CCSID_04948("IBM-852 (CCSID 04948); Latin-2 Personal Computer", 0x10021354, 1, x0012), - IBM_855__CCSID_04951("IBM-855 (CCSID 04951); Cyrillic Personal Computer", 0x10021357, 1, x0015), - IBM_856__CCSID_04952("IBM-856 (CCSID 04952); Hebrew PC Data", 0x10021358, 1, x0018), - IBM_857__CCSID_04953("IBM-857 (CCSID 04953); Turkish Latin-5 PC Data", 0x10021359, 1, x0019), - IBM_864__CCSID_04960("IBM-864 (CCSID 04960); Arabic PC Data (all shapes)", 0x10021360, 1, x0016), - IBM_868__CCSID_04964("IBM-868 (CCSID 04964); PC Data for Urdu", 0x10021364, 1, x0016), - IBM_869__CCSID_04965("IBM-869 (CCSID 04965); Greek PC Data", 0x10021365, 1, x0017), - IBM_5026__CCSID_05026("IBM-5026 (CCSID 05026); Japanese Katakana-Kanji Host Mixed", 0x100213a2, 2, x0080, x0081), - IBM_5031__CCSID_05031("IBM-5031 (CCSID 05031); S-Ch Host MBCS", 0x100213a7, 2, x0001, x0300), - IBM_1027_and__300__CCSID_05035("IBM-1027 and -300 (CCSID 05035); Japanese Latin-Kanji Host Mixed", 0x100213ab, 2, x0080, x0081), - IBM_5048__CCSID_05048("IBM-5048 (CCSID 05048); Japanese Kanji characters; superset of JIS X0208:1990 (and 1983)", 0x100213b8, 2, x0081), - IBM_5049__CCSID_05049("IBM-5049 (CCSID 05049); Japanese Kanji characters; superset of JIS X0212:1990", 0x100213b9, 2, x0082), - IBM_5067__CCSID_05067("IBM-5067 (CCSID 05067); Korean Hangul and Hanja; superset of KS C5601:1987", 0x100213cb, 2, x0100), - IBM_420__CCSID_08612("IBM-420 (CCSID 08612); Arabic (base shapes only)", 0x100221a4, 1, x0016), - IBM_833__CCSID_09025("IBM-833 (CCSID 09025); Korean Host SBCS", 0x10022341, 1, x0001), - IBM_834__CCSID_09026("IBM-834 (CCSID 09026); Korean Host DBCS incl 1880 UDC", 0x10022342, 2, x0100), - IBM_838__CCSID_09030("IBM-838 (CCSID 09030); Thai Host Extended SBCS", 0x10022346, 1, x0200), - IBM_864__CCSID_09056("IBM-864 (CCSID 09056); Arabic PC Data (unshaped)", 0x10022360, 1, x0016), - IBM_874__CCSID_09066("IBM-874 (CCSID 09066); Thai PC Display Extended SBCS", 0x1002236a, 1, x0200), - IBM_9125__CCSID_09125("IBM-9125 (CCSID 09125); Korean Host Mixed incl 1880 UDC", 0x100223a5, 2, x0001, x0100), - IBM_850__CCSID_25426("IBM-850 (CCSID 25426); Multilingual IBM PC Display-MLP", 0x10026352, 1, x0011), - IBM_856__CCSID_25432("IBM-856 (CCSID 25432); Hebrew PC Display (extensions)", 0x10026358, 1, x0018), - IBM_1042__CCSID_25618("IBM-1042 (CCSID 25618); S-Ch PC Display Ext SBCS", 0x10026412, 1, x0001), - IBM_037__CCSID_28709("IBM-037 (CCSID 28709); T-Ch Host Extended SBCS", 0x10027025, 1, x0001), - IBM_856__CCSID_33624("IBM-856 (CCSID 33624); Hebrew PC Display", 0x10028358, 1, x0018), - IBM33722__CCSID_33722("IBM33722 (CCSID 33722); Japanese EUC JISx201,208,212", 0x100283ba, 3, x0080, x0081, x0082), - HTCsjis("HTCsjis; Hitachi SJIS 90-1", 0x10030001, 2, x0001, x0080, x0081), - HTCujis("HTCujis; Hitachi eucJP 90-1", 0x10030002, 2, x0001, x0080, x0081), - Fujitsu_U90("Fujitsu U90; Japanese EUC", 0x10040001, 3, x0001, x0080, x0081), - Fujitsu_S90("Fujitsu S90; Japanese EUC", 0x10040002, 3, x0001, x0080, x0081), - Fujitsu_R90("Fujitsu R90; Fujitsu Shift JIS", 0x10040003, 2, x0001, x0080, x0081), - EBCDIC_ASCII__and_JEF("EBCDIC(ASCII) and JEF; Japanese encoding method for mainframe", 0x10040004, 3, x0001, x0081), - EBCDIC_Katakana__and_JEF("EBCDIC(Katakana) and JEF; Japanese encoding method for mainframe", 0x10040005, 3, x0001, x0080, x0081), - EBCDIC_Japanese_English__and_JEF("EBCDIC(Japanese English) and JEF; Japanese encoding method for mainframe", 0x10040006, 3, x0001, x0081), + NONE("none", 0x00000000), + ISO_LATIN_1("ISO 8859-1:1987; Latin Alphabet No. 1", 0x00010001, x0011), + ISO_LATIN_2("ISO 8859-2:1987; Latin Alphabet No. 2", 0x00010002, x0012), + ISO_LATIN_3("ISO 8859-3:1988; Latin Alphabet No. 3", 0x00010003, x0013), + ISO_LATIN_4("ISO 8859-4:1988; Latin Alphabet No. 4", 0x00010004, x0014), + ISO_8859_5("ISO/IEC 8859-5:1988; Latin-Cyrillic Alphabet", 0x00010005, x0015), + ISO_8859_6("ISO 8859-6:1987; Latin-Arabic Alphabet", 0x00010006, x0016), + ISO_8859_7("ISO 8859-7:1987; Latin-Greek Alphabet", 0x00010007, x0017), + ISO_8859_8("ISO 8859-8:1988; Latin-Hebrew Alphabet", 0x00010008, x0018), + ISO_8859_9("ISO/IEC 8859-9:1989; Latin Alphabet No. 5", 0x00010009, x0019), + ISO_IEC_8859_10_1992("ISO/IEC 8859-10:1992; Latin Alphabet No. 6", 0x0001000a, x001a), + ISO_IEC_8859_15_1999("ISO/IEC 8859-15:1999; Latin Alphabet No. 9", 0x0001000f, x0011), + ISO_646_IRV("ISO 646:1991 IRV (International Reference Version)", 0x00010020, x0001), + UCS_2("ISO/IEC 10646-1:1993; UCS-2, Level 1", 0x00010100, x1000), + UCS2_L2("ISO/IEC 10646-1:1993; UCS-2, Level 2", 0x00010101, x1000), + UCS2_L3("ISO/IEC 10646-1:1993; UCS-2, Level 3", 0x00010102, x1000), + USC4_L1("ISO/IEC 10646-1:1993; UCS-4, Level 1", 0x00010104, x1000), + USC4_L2("ISO/IEC 10646-1:1993; UCS-4, Level 2", 0x00010105, x1000), + USC4_L3("ISO/IEC 10646-1:1993; UCS-4, Level 3", 0x00010106, x1000), + UTF1("ISO/IEC 10646-1:1993; UTF-1, UCS Transformation Format 1", 0x00010108, x1000), + UTF_16("ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form", 0x00010109, x1000), + JIS_X0201_1976("JIS X0201:1976; Japanese phonetic characters", 0x00030001, x0080), + JIS_X0208_1978("JIS X0208:1978 Japanese Kanji Graphic Characters", 0x00030004, x0081), + JIS_X0208_1983("JIS X0208:1983 Japanese Kanji Graphic Characters", 0x00030005, x0081), + JIS_X0208_1990("JIS X0208:1990 Japanese Kanji Graphic Characters", 0x00030006, x0081), + JIS_X0212_1990("JIS X0212:1990; Supplementary Japanese Kanji Graphic Chars", 0x0003000a, x0082), + JIS_eucJP_1993("JIS eucJP:1993; Japanese EUC", 0x00030010, x0011, x0080, x0081, x0082), + KS_C5601_1987("KS C5601:1987; Korean Hangul and Hanja Graphic Characters", 0x00040001, x0100), + KS_C5657_1991("KS C5657:1991; Supplementary Korean Graphic Characters", 0x00040002, x0101), + KS_eucKR_1991("KS eucKR:1991; Korean EUC", 0x0004000a, x0011, x0100, x0101), + CNS_11643_1986("CNS 11643:1986; Taiwanese Hanzi Graphic Characters", 0x00050001, x0180), + CNS_11643_1992("CNS 11643:1992; Taiwanese Extended Hanzi Graphic Chars", 0x00050002, x0181), + CNS_eucTW_1991("CNS eucTW:1991; Taiwanese EUC", 0x0005000a, x0001, x0180), + CNS_eucTW_1993("CNS eucTW:1993; Taiwanese EUC", 0x00050010, x0001, x0181), + TIS_620_2529("TIS 620-2529, Thai characters", 0x000b0001, x0200), + TTB_CCDC_1984("TTB CCDC:1984; Chinese Code for Data Communications", 0x000d0001, x0180), + OSF_Japanese_UJIS("OSF Japanese UJIS", 0x05000010, x0001, x0080, x0081), + OSF_Japanese_SJIS_1("OSF Japanese SJIS-1", 0x05000011, x0001, x0080, x0081), + OSF_Japanese_SJIS_2("OSF Japanese SJIS-2", 0x05000012, x0001, x0080, x0081), + UTF_8("X/Open UTF-8; UCS Transformation Format 8 (UTF-8)", 0x05010001, x1000), + JVC_eucJP("JVC_eucJP", 0x05020001, x0001, x0080, x0081, x0082), + JVC_SJIS("JVC_SJIS", 0x05020002, x0001, x0080, x0081), + DEC_Kanji("DEC Kanji", 0x10000001, x0011, x0080, x0081), + Super_DEC_Kanji("Super DEC Kanji", 0x10000002, x0011, x0080, x0081, x0082), + DEC_Shift_JIS("DEC Shift JIS", 0x10000003, x0011, x0080, x0081), + HP_roman8("HP roman8; English and Western European languages", 0x10010001, x0011), + HP_kana8("HP kana8; Japanese katakana (incl JIS X0201:1976)", 0x10010002, x0080), + HP_arabic8("HP arabic8; Arabic", 0x10010003, x0016), + HP_greek8("HP greek8; Greek", 0x10010004, x0017), + HP_hebrew8("HP hebrew8; Hebrew", 0x10010005, x0018), + HP_turkish8("HP turkish8; Turkish", 0x10010006, x0013, x0019), + HP15CN("HP15CN; encoding method for Simplified Chinese", 0x10010007, x0001, x0300), + HP_big5("HP big5; encoding method for Traditional Chinese", 0x10010008, x0001, x0180), + HP_japanese15__sjis("HP japanese15 (sjis); Shift-JIS for mainframe (incl JIS X0208:1990)", 0x10010009, x0001, x0080, x0081), + HP_sjishi("HP sjishi; Shift-JIS for HP user (incl JIS X0208:1990)", 0x1001000a, x0001, x0080, x0081), + HP_sjispc("HP sjispc; Shift-JIS for PC (incl JIS X0208:1990)", 0x1001000b, x0001, x0080, x0081), + HP_ujis("HP ujis; EUC (incl JIS X0208:1990)", 0x1001000c, x0001, x0080, x0081), + IBM_037__CCSID_00037("IBM-037 (CCSID 00037); CECP for USA, Canada, NL, Ptgl, Brazil, Australia, NZ", 0x10020025, x0011), + IBM_273__CCSID_00273("IBM-273 (CCSID 00273); CECP for Austria, Germany", 0x10020111, x0011), + IBM_277__CCSID_00277("IBM-277 (CCSID 00277); CECP for Denmark, Norway", 0x10020115, x0011), + IBM_278__CCSID_00278("IBM-278 (CCSID 00278); CECP for Finland, Sweden", 0x10020116, x0011), + IBM_280__CCSID_00280("IBM-280 (CCSID 00280); CECP for Italy", 0x10020118, x0011), + IBM_282__CCSID_00282("IBM-282 (CCSID 00282); CECP for Portugal", 0x1002011a, x0011), + IBM_284__CCSID_00284("IBM-284 (CCSID 00284); CECP for Spain, Latin America (Spanish)", 0x1002011c, x0011), + IBM_285__CCSID_00285("IBM-285 (CCSID 00285); CECP for United Kingdom", 0x1002011d, x0011), + IBM_290__CCSID_00290("IBM-290 (CCSID 00290); Japanese Katakana Host Ext SBCS", 0x10020122, x0080), + IBM_297__CCSID_00297("IBM-297 (CCSID 00297); CECP for France", 0x10020129, x0011), + IBM_300__CCSID_00300("IBM-300 (CCSID 00300); Japanese Host DBCS incl 4370 UDC", 0x1002012c, x0081), + IBM_301__CCSID_00301("IBM-301 (CCSID 00301); Japanese PC Data DBCS incl 1880 UDC", 0x1002012d, x0081), + IBM_420__CCSID_00420("IBM-420 (CCSID 00420); Arabic (presentation shapes)", 0x100201a4, x0016), + IBM_424__CCSID_00424("IBM-424 (CCSID 00424); Hebrew", 0x100201a8, x0018), + IBM_437__CCSID_00437("IBM-437 (CCSID 00437); PC USA", 0x100201b5, x0011), + IBM_500__CCSID_00500("IBM-500 (CCSID 00500); CECP for Belgium, Switzerland", 0x100201f4, x0011), + IBM_833__CCSID_00833("IBM-833 (CCSID 00833); Korean Host Extended SBCS", 0x10020341, x0001), + IBM_834__CCSID_00834("IBM-834 (CCSID 00834); Korean Host DBCS incl 1227 UDC", 0x10020342, x0100), + IBM_835__CCSID_00835("IBM-835 (CCSID 00835); T-Ch Host DBCS incl 6204 UDC", 0x10020343, x0180), + IBM_836__CCSID_00836("IBM-836 (CCSID 00836); S-Ch Host Extended SBCS", 0x10020344, x0001), + IBM_837__CCSID_00837("IBM-837 (CCSID 00837); S-Ch Host DBCS incl 1880 UDC", 0x10020345, x0300), + IBM_838__CCSID_00838("IBM-838 (CCSID 00838); Thai Host Extended SBCS", 0x10020346, x0200), + IBM_839__CCSID_00839("IBM-839 (CCSID 00839); Thai Host DBCS incl 374 UDC", 0x10020347, x0200), + IBM_850__CCSID_00850("IBM-850 (CCSID 00850); Multilingual IBM PC Data-MLP 222", 0x10020352, x0011), + IBM_852__CCSID_00852("IBM-852 (CCSID 00852); Multilingual Latin-2", 0x10020354, x0012), + IBM_855__CCSID_00855("IBM-855 (CCSID 00855); Cyrillic PC Data", 0x10020357, x0015), + IBM_856__CCSID_00856("IBM-856 (CCSID 00856); Hebrew PC Data (extensions)", 0x10020358, x0018), + IBM_857__CCSID_00857("IBM-857 (CCSID 00857); Turkish Latin-5 PC Data", 0x10020359, x0019), + IBM_861__CCSID_00861("IBM-861 (CCSID 00861); PC Data Iceland", 0x1002035d, x0011), + IBM_862__CCSID_00862("IBM-862 (CCSID 00862); PC Data Hebrew", 0x1002035e, x0018), + IBM_863__CCSID_00863("IBM-863 (CCSID 00863); PC Data Canadian French", 0x1002035f, x0011), + IBM_864__CCSID_00864("IBM-864 (CCSID 00864); Arabic PC Data", 0x10020360, x0016), + IBM_866__CCSID_00866("IBM-866 (CCSID 00866); PC Data Cyrillic 2", 0x10020362, x0015), + IBM_868__CCSID_00868("IBM-868 (CCSID 00868); Urdu PC Data", 0x10020364, x0016), + IBM_869__CCSID_00869("IBM-869 (CCSID 00869); Greek PC Data", 0x10020365, x0017), + IBM_870__CCSID_00870("IBM-870 (CCSID 00870); Multilingual Latin-2 EBCDIC", 0x10020366, x0012), + IBM_871__CCSID_00871("IBM-871 (CCSID 00871); CECP for Iceland", 0x10020367, x0011), + IBM_874__CCSID_00874("IBM-874 (CCSID 00874); Thai PC Display Extended SBCS", 0x1002036a, x0200), + IBM_875__CCSID_00875("IBM-875 (CCSID 00875); Greek", 0x1002036b, x0017), + IBM_880__CCSID_00880("IBM-880 (CCSID 00880); Multilingual Cyrillic", 0x10020370, x0015), + IBM_891__CCSID_00891("IBM-891 (CCSID 00891); Korean PC Data SBCS", 0x1002037b, x0001), + IBM_896__CCSID_00896("IBM-896 (CCSID 00896); Japanese Katakana characters; superset of JIS X0201:1976", 0x10020380, x0080), + IBM_897__CCSID_00897("IBM-897 (CCSID 00897); PC Data Japanese SBCS (use with CP 00301)", 0x10020381, x0080), + IBM_903__CCSID_00903("IBM-903 (CCSID 00903); PC Data Simplified Chinese SBCS (use with DBCS)", 0x10020387, x0001), + IBM_904__CCSID_00904("IBM-904 (CCSID 00904); PC Data Traditional Chinese SBCS (use with DBCS)", 0x10020388, x0001), + IBM_918__CCSID_00918("IBM-918 (CCSID 00918); Urdu", 0x10020396, x0016), + IBM_921__CCSID_00921("IBM-921 (CCSID 00921); Baltic 8-Bit", 0x10020399, x001a), + IBM_922__CCSID_00922("IBM-922 (CCSID 00922); Estonia 8-Bit", 0x1002039a, x001a), + IBM_926__CCSID_00926("IBM-926 (CCSID 00926); Korean PC Data DBCS incl 1880 UDC", 0x1002039e, x0100), + IBM_927__CCSID_00927("IBM-927 (CCSID 00927); T-Ch PC Data DBCS incl 6204 UDC", 0x1002039f, x0180), + IBM_928__CCSID_00928("IBM-928 (CCSID 00928); S-Ch PC Data DBCS incl 1880 UDC", 0x100203a0, x0300), + IBM_929__CCSID_00929("IBM-929 (CCSID 00929); Thai PC Data DBCS incl 374 UDC", 0x100203a1, x0200), + IBM_930__CCSID_00930("IBM-930 (CCSID 00930); Kat-Kanji Host MBCS Ext-SBCS", 0x100203a2, x0080, x0081), + IBM_932__CCSID_00932("IBM-932 (CCSID 00932); Japanese PC Data Mixed", 0x100203a4, x0080, x0081), + IBM_933__CCSID_00933("IBM-933 (CCSID 00933); Korean Host Extended SBCS", 0x100203a5, x0001, x0100), + IBM_934__CCSID_00934("IBM-934 (CCSID 00934); Korean PC Data Mixed", 0x100203a6, x0001, x0100), + IBM_935__CCSID_00935("IBM-935 (CCSID 00935); S-Ch Host Mixed", 0x100203a7, x0001, x0300), + IBM_936__CCSID_00936("IBM-936 (CCSID 00936); PC Data S-Ch MBCS", 0x100203a8, x0001, x0300), + IBM_937__CCSID_00937("IBM-937 (CCSID 00937); T-Ch Host Mixed", 0x100203a9, x0001, x0180), + IBM_938__CCSID_00938("IBM-938 (CCSID 00938); PC Data T-Ch MBCS", 0x100203aa, x0001, x0180), + IBM_939__CCSID_00939("IBM-939 (CCSID 00939); Latin-Kanji Host MBCS", 0x100203ab, x0080, x0081), + IBM_941__CCSID_00941("IBM-941 (CCSID 00941); Japanese PC DBCS for Open", 0x100203ad, x0081), + IBM_942__CCSID_00942("IBM-942 (CCSID 00942); Japanese PC Data Mixed", 0x100203ae, x0080, x0081), + IBM_943__CCSID_00943("IBM-943 (CCSID 00943); Japanese PC MBCS for Open", 0x100203af, x0080, x0081), + IBM_946__CCSID_00946("IBM-946 (CCSID 00946); S-Ch PC Data Mixed", 0x100203b2, x0001, x0300), + IBM_947__CCSID_00947("IBM-947 (CCSID 00947); T-Ch PC Data DBCS incl 6204 UDC", 0x100203b3, x0180), + IBM_948__CCSID_00948("IBM-948 (CCSID 00948); T-Ch PC Data Mixed", 0x100203b4, x0001, x0180), + IBM_949__CCSID_00949("IBM-949 (CCSID 00949); IBM KS PC Data Mixed", 0x100203b5, x0001, x0100), + IBM_950__CCSID_00950("IBM-950 (CCSID 00950); T-Ch PC Data Mixed", 0x100203b6, x0001, x0180), + IBM_951__CCSID_00951("IBM-951 (CCSID 00951); IBM KS PC Data DBCS incl 1880 UDC", 0x100203b7, x0100), + IBM_955__CCSID_00955("IBM-955 (CCSID 00955); Japan Kanji characters; superset of JIS X0208:1978", 0x100203bb, x0081), + IBM_964__CCSID_00964("IBM-964 (CCSID 00964); T-Chinese EUC CNS1163 plane 1,2", 0x100203c4, x0001, x0180), + IBM_970__CCSID_00970("IBM-970 (CCSID 00970); Korean EUC", 0x100203ca, x0011, x0100, x0101), + IBM_1006__CCSID_01006("IBM-1006 (CCSID 01006); Urdu 8-bit", 0x100203ee, x0016), + IBM_1025__CCSID_01025("IBM-1025 (CCSID 01025); Cyrillic Multilingual", 0x10020401, x0015), + IBM_1026__CCSID_01026("IBM-1026 (CCSID 01026); Turkish Latin-5", 0x10020402, x0019), + IBM_1027__CCSID_01027("IBM-1027 (CCSID 01027); Japanese Latin Host Ext SBCS", 0x10020403, x0080), + IBM_1040__CCSID_01040("IBM-1040 (CCSID 01040); Korean PC Data Extended SBCS", 0x10020410, x0001), + IBM_1041__CCSID_01041("IBM-1041 (CCSID 01041); Japanese PC Data Extended SBCS", 0x10020411, x0080), + IBM_1043__CCSID_01043("IBM-1043 (CCSID 01043); T-Ch PC Data Extended SBCS", 0x10020413, x0001), + IBM_1046__CCSID_01046("IBM-1046 (CCSID 01046); Arabic PC Data", 0x10020416, x0016), + IBM_1047__CCSID_01047("IBM-1047 (CCSID 01047); Latin-1 Open System", 0x10020417, x0011), + IBM_1088__CCSID_01088("IBM-1088 (CCSID 01088); IBM KS Code PC Data SBCS", 0x10020440, x0001), + IBM_1097__CCSID_01097("IBM-1097 (CCSID 01097); Farsi", 0x10020449, x0016), + IBM_1098__CCSID_01098("IBM-1098 (CCSID 01098); Farsi PC Data", 0x1002044a, x0016), + IBM_1112__CCSID_01112("IBM-1112 (CCSID 01112); Baltic Multilingual", 0x10020458, x001a), + IBM_1114__CCSID_01114("IBM-1114 (CCSID 01114); T-Ch PC Data SBCS (IBM BIG-5)", 0x1002045a, x0001), + IBM_1115__CCSID_01115("IBM-1115 (CCSID 01115); S-Ch PC Data SBCS (IBM GB)", 0x1002045b, x0001), + IBM_1122__CCSID_01122("IBM-1122 (CCSID 01122); Estonia", 0x10020462, x001a), + IBM_1250__CCSID_01250("IBM-1250 (CCSID 01250); MS Windows Latin-2", 0x100204e2, x0012), + IBM_1251__CCSID_01251("IBM-1251 (CCSID 01251); MS Windows Cyrillic", 0x100204e3, x0015), + IBM_1252__CCSID_01252("IBM-1252 (CCSID 01252); MS Windows Latin-1", 0x100204e4, x0011), + IBM_1253__CCSID_01253("IBM-1253 (CCSID 01253); MS Windows Greek", 0x100204e5, x0017), + IBM_1254__CCSID_01254("IBM-1254 (CCSID 01254); MS Windows Turkey", 0x100204e6, x0019), + IBM_1255__CCSID_01255("IBM-1255 (CCSID 01255); MS Windows Hebrew", 0x100204e7, x0018), + IBM_1256__CCSID_01256("IBM-1256 (CCSID 01256); MS Windows Arabic", 0x100204e8, x0016), + IBM_1257__CCSID_01257("IBM-1257 (CCSID 01257); MS Windows Baltic", 0x100204e9, x001a), + IBM_1380__CCSID_01380("IBM-1380 (CCSID 01380); S-Ch PC Data DBCS incl 1880 UDC", 0x10020564, x0300), + IBM_1381__CCSID_01381("IBM-1381 (CCSID 01381); S-Ch PC Data Mixed incl 1880 UDC", 0x10020565, x0001, x0300), + IBM_1383__CCSID_01383("IBM-1383 (CCSID 01383); S-Ch EUC GB 2312-80 set (1382)", 0x10020567, x0001, x0300), + IBM_300__CCSID_04396("IBM-300 (CCSID 04396); Japanese Host DBCS incl 1880 UDC", 0x1002112c, x0081), + IBM_850__CCSID_04946("IBM-850 (CCSID 04946); Multilingual IBM PC Data-190", 0x10021352, x0011), + IBM_852__CCSID_04948("IBM-852 (CCSID 04948); Latin-2 Personal Computer", 0x10021354, x0012), + IBM_855__CCSID_04951("IBM-855 (CCSID 04951); Cyrillic Personal Computer", 0x10021357, x0015), + IBM_856__CCSID_04952("IBM-856 (CCSID 04952); Hebrew PC Data", 0x10021358, x0018), + IBM_857__CCSID_04953("IBM-857 (CCSID 04953); Turkish Latin-5 PC Data", 0x10021359, x0019), + IBM_864__CCSID_04960("IBM-864 (CCSID 04960); Arabic PC Data (all shapes)", 0x10021360, x0016), + IBM_868__CCSID_04964("IBM-868 (CCSID 04964); PC Data for Urdu", 0x10021364, x0016), + IBM_869__CCSID_04965("IBM-869 (CCSID 04965); Greek PC Data", 0x10021365, x0017), + IBM_5026__CCSID_05026("IBM-5026 (CCSID 05026); Japanese Katakana-Kanji Host Mixed", 0x100213a2, x0080, x0081), + IBM_5031__CCSID_05031("IBM-5031 (CCSID 05031); S-Ch Host MBCS", 0x100213a7, x0001, x0300), + IBM_1027_and__300__CCSID_05035("IBM-1027 and -300 (CCSID 05035); Japanese Latin-Kanji Host Mixed", 0x100213ab, x0080, x0081), + IBM_5048__CCSID_05048("IBM-5048 (CCSID 05048); Japanese Kanji characters; superset of JIS X0208:1990 (and 1983)", 0x100213b8, x0081), + IBM_5049__CCSID_05049("IBM-5049 (CCSID 05049); Japanese Kanji characters; superset of JIS X0212:1990", 0x100213b9, x0082), + IBM_5067__CCSID_05067("IBM-5067 (CCSID 05067); Korean Hangul and Hanja; superset of KS C5601:1987", 0x100213cb, x0100), + IBM_420__CCSID_08612("IBM-420 (CCSID 08612); Arabic (base shapes only)", 0x100221a4, x0016), + IBM_833__CCSID_09025("IBM-833 (CCSID 09025); Korean Host SBCS", 0x10022341, x0001), + IBM_834__CCSID_09026("IBM-834 (CCSID 09026); Korean Host DBCS incl 1880 UDC", 0x10022342, x0100), + IBM_838__CCSID_09030("IBM-838 (CCSID 09030); Thai Host Extended SBCS", 0x10022346, x0200), + IBM_864__CCSID_09056("IBM-864 (CCSID 09056); Arabic PC Data (unshaped)", 0x10022360, x0016), + IBM_874__CCSID_09066("IBM-874 (CCSID 09066); Thai PC Display Extended SBCS", 0x1002236a, x0200), + IBM_9125__CCSID_09125("IBM-9125 (CCSID 09125); Korean Host Mixed incl 1880 UDC", 0x100223a5, x0001, x0100), + IBM_850__CCSID_25426("IBM-850 (CCSID 25426); Multilingual IBM PC Display-MLP", 0x10026352, x0011), + IBM_856__CCSID_25432("IBM-856 (CCSID 25432); Hebrew PC Display (extensions)", 0x10026358, x0018), + IBM_1042__CCSID_25618("IBM-1042 (CCSID 25618); S-Ch PC Display Ext SBCS", 0x10026412, x0001), + IBM_037__CCSID_28709("IBM-037 (CCSID 28709); T-Ch Host Extended SBCS", 0x10027025, x0001), + IBM_856__CCSID_33624("IBM-856 (CCSID 33624); Hebrew PC Display", 0x10028358, x0018), + IBM33722__CCSID_33722("IBM33722 (CCSID 33722); Japanese EUC JISx201,208,212", 0x100283ba, x0080, x0081, x0082), + HTCsjis("HTCsjis; Hitachi SJIS 90-1", 0x10030001, x0001, x0080, x0081), + HTCujis("HTCujis; Hitachi eucJP 90-1", 0x10030002, x0001, x0080, x0081), + Fujitsu_U90("Fujitsu U90; Japanese EUC", 0x10040001, x0001, x0080, x0081), + Fujitsu_S90("Fujitsu S90; Japanese EUC", 0x10040002, x0001, x0080, x0081), + Fujitsu_R90("Fujitsu R90; Fujitsu Shift JIS", 0x10040003, x0001, x0080, x0081), + EBCDIC_ASCII__and_JEF("EBCDIC(ASCII) and JEF; Japanese encoding method for mainframe", 0x10040004, x0001, x0081), + EBCDIC_Katakana__and_JEF("EBCDIC(Katakana) and JEF; Japanese encoding method for mainframe", 0x10040005, x0001, x0080, x0081), + EBCDIC_Japanese_English__and_JEF("EBCDIC(Japanese English) and JEF; Japanese encoding method for mainframe", 0x10040006, x0001, x0081), ; private static final Map REGISTRY; @@ -263,11 +256,8 @@ public enum CodeSetInfo { REGISTRY = unmodifiableMap(m); } - public final short max_bytes; - final String description; public final int id; - final CharMapInfo charMap; /** * The IDs of these charsets had some meaning at some point. @@ -284,23 +274,19 @@ enum Charset { private final int charsets; - CodeSetInfo(String desc, int reg_id, int max_width, CharMapInfo charMap, Charset... charsets) { + CodeSetInfo(String desc, int reg_id, Charset... charsets) { this.description = desc; this.id = reg_id; - this.max_bytes = (short)max_width; this.charsets = Charset.setOf(charsets); - this.charMap = charMap; } - CodeSetInfo(String desc, int reg_id, int max_width, Charset... charsets) { - this(desc, reg_id, max_width, null, charsets); - } + public static CodeSetInfo forName(String name) { return Stream.of(CodeSetInfo.values()).filter(info -> info.description.contains(name)).findFirst().orElse(NONE); } public static int getRegistryIdForName(String name) { requireNonNull(name); // Check if codeset name is listed in registry // Return first match so that shortcuts can be used - return Stream.of(CodeSetInfo.values()).filter(info -> info.description.contains(name)).findFirst().orElse(NONE).id; + return forName(name).id; } /** @return null if registryId unknown */ diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java index d9b5cf715..2e84412ab 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java @@ -64,29 +64,22 @@ static CodeSetComponentInfo getCodeSetInfoFromComponents(ORBInstance orbInstance .findFirst().orElse(null); } - // - // Get code converters from ProfileInfo and/or IOR - // - static CodeConverters getCodeConverters(ORBInstance orbInstance, ProfileInfo profileInfo) { - // - // Set up code converters - // - // + static CodecPair getNegotiatedCodecs(ORBInstance orbInstance, ProfileInfo profileInfo) { // Other transmission codesets than the defaults can only be // determined if a codeset profile was present in the IOR. - // The fallbacks in this case according to the specification - // are UTF-8 (not ISOLATIN1!) and UTF-16 (not UCS2!). - // - final CodeSetComponentInfo info = getCodeSetInfoFromComponents(orbInstance, profileInfo); - if (info == null) return CodeConverters.create(ISO_LATIN_1.id, orbInstance.getDefaultWcs()); + // defaults if no codeset profile was found in the IOR + if (info == null) return CodecPair.create(ISO_LATIN_1.id, orbInstance.getDefaultWcs()); CodeSetComponent client_cs = createCodeSetComponent(orbInstance.getNativeCs(), false); CodeSetComponent client_wcs = createCodeSetComponent(orbInstance.getNativeWcs(), true); + // A codeset profile was present. + // The fallbacks in this case according to the specification + // are UTF-8 (not ISOLATIN1!) and UTF-16 (not UCS2!). final int tcs_c = determineTCS(client_cs, info.ForCharData, UTF_8.id); final int tcs_wc = determineTCS(client_wcs, info.ForWcharData, UTF_16.id); - return CodeConverters.create(tcs_c, tcs_wc); + return CodecPair.create(tcs_c, tcs_wc); } static CodeSetContext extractCodeSetContext(ServiceContext csSC) { diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java similarity index 58% rename from yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java rename to yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java index fb10e27c0..7401931ff 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeConverters.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java @@ -22,44 +22,52 @@ import java.util.Objects; -import static org.apache.yoko.codecs.CharCodec.NULL_CODEC; +import static org.apache.yoko.codecs.CharCodec.DEFAULT_CHAR_CODEC; +import static org.apache.yoko.codecs.CharCodec.NULL_CHAR_CODEC; +import static org.apache.yoko.codecs.WcharCodec.NULL_WCHAR_CODEC; -// This class may look immutable, but charCodec can contain state (while reading a surrogate pair from UTF-8) -public final class CodeConverters { - static final CodeConverters COLLOCATED = new CodeConverters(NULL_CODEC, NULL_CODEC); +// This class may look immutable, but charCodec can contain state (while reading/writing a surrogate pair from/to UTF-8) +public final class CodecPair { + /** + * The default codecs for GIOP 1.0. + * TODO: consider whether we need an UNSUPPORTED wchar codec that throws exceptions for wchars + */ + static final CodecPair DEFAULT = new CodecPair(DEFAULT_CHAR_CODEC, WcharCodec.DEFAULT_WCHAR_CODEC); + static final CodecPair COLLOCATED = new CodecPair(NULL_CHAR_CODEC, NULL_WCHAR_CODEC); public final CharCodec charCodec; public final WcharCodec wcharCodec; - private CodeConverters(CharCodec cc, WcharCodec wc) { + private CodecPair(CharCodec cc, WcharCodec wc) { this.charCodec = cc; this.wcharCodec = wc; } - private CodeConverters(CodeConverters that) { + private CodecPair(CodecPair that) { this(that.charCodec.getInstanceOrCopy(), that.wcharCodec.getInstanceOrCopy()); } - public static CodeConverters createCopy(CodeConverters template) { - if (template == null) return COLLOCATED; + public static CodecPair createCopy(CodecPair template) { + if (template == null) return DEFAULT; + if (template == DEFAULT) return DEFAULT; if (template == COLLOCATED) return COLLOCATED; - return new CodeConverters(template); + return new CodecPair(template); } - public static CodeConverters create(int tcs, int twcs) { + public static CodecPair create(int tcs, int twcs) { CharCodec cc = CharCodec.forRegistryId(tcs); WcharCodec wc = WcharCodec.forRegistryId(twcs); - return new CodeConverters(cc, wc); + return new CodecPair(cc, wc); } - public static CodeConverters createForWcharWriteOnly() { - return new CodeConverters(null, WcharCodec.getDefault()); + public static CodecPair createForWcharWriteOnly() { + return new CodecPair(null, WcharCodec.getDefault()); } @Override public boolean equals(Object o) { - if (!(o instanceof CodeConverters)) return false; - CodeConverters that = (CodeConverters) o; + if (!(o instanceof CodecPair)) return false; + CodecPair that = (CodecPair) o; return Objects.equals(charCodec, that.charCodec) && Objects.equals(wcharCodec, that.wcharCodec); } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java index dfc9b438a..bdb9498d1 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java @@ -17,7 +17,7 @@ */ package org.apache.yoko.orb.OB; -import static org.apache.yoko.orb.OB.CodeConverters.COLLOCATED; +import static org.apache.yoko.orb.OB.CodecPair.COLLOCATED; import org.apache.yoko.orb.CORBA.YokoOutputStream; import org.apache.yoko.orb.CORBA.OutputStreamHolder; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java index 3a2e49292..e0b90e5bf 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Downcall.java @@ -429,8 +429,8 @@ public final void setNoException(YokoInputStream in) { Assert.ensure(responseExpected_); in_ = in; in_._OB_ORBInstance(orbInstance_); - CodeConverters codeConverters = client_.codeConverters(); - in_._OB_codeConverters(codeConverters, GiopVersion.get(profileInfo_.major, profileInfo_.minor)); + CodecPair codecs = client_.codecs(); + in_.setCodecsAndGiopVersion(codecs, GiopVersion.get(profileInfo_.major, profileInfo_.minor)); } if (null != stateWaitCondition) stateWaitCondition.signalAll(); } @@ -443,8 +443,8 @@ public final void setUserException(YokoInputStream in) { state = State.USER_EXCEPTION; in_ = in; in_._OB_ORBInstance(orbInstance_); - CodeConverters codeConverters = client_.codeConverters(); - in_._OB_codeConverters(codeConverters, GiopVersion.get(profileInfo_.major, profileInfo_.minor)); + CodecPair codecs = client_.codecs(); + in_.setCodecsAndGiopVersion(codecs, GiopVersion.get(profileInfo_.major, profileInfo_.minor)); if (null != stateWaitCondition) stateWaitCondition.signalAll(); } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java index 8456c49d8..fef0789cd 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/DowncallStub.java @@ -477,11 +477,11 @@ public YokoOutputStream setupRequest( // Prepare a polling request from a portable stub // // public org.apache.yoko.orb.CORBA.OutputStream - public CodeConverters setupPollingRequest(ServiceContextListHolder sclHolder, OutputStreamHolder out) throws FailureException { + public CodecPair setupPollingRequest(ServiceContextListHolder sclHolder, OutputStreamHolder out) throws FailureException { // Obtain information regarding our target Client client = getClientProfilePair().client; - out.value = new YokoOutputStream(client.codeConverters(), GIOP1_2); + out.value = new YokoOutputStream(client.codecs(), GIOP1_2); sclHolder.value = client.getAMIRouterContexts().toArray(); @@ -493,7 +493,7 @@ public CodeConverters setupPollingRequest(ServiceContextListHolder sclHolder, Ou ctx.downcall = null; out.value._OB_invocationContext(ctx); - return client.codeConverters(); + return client.codecs(); } // Creates an output stream that holds an AMI router request. Note @@ -514,7 +514,7 @@ public GIOPOutgoingMessage AMIRouterPreMarshal(String operation, final Client client = cp.client; info.value = cp.profile; - out.value = new YokoOutputStream(writeBuffer, client.codeConverters(), GIOP1_2); + out.value = new YokoOutputStream(writeBuffer, client.codecs(), GIOP1_2); ServiceContexts contexts = client.getAMIRouterContexts(); GIOPOutgoingMessage outgoing = new GIOPOutgoingMessage(orbInstance_, out.value, info.value); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java index 3eb7515c1..a11047143 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPClient.java @@ -31,7 +31,6 @@ import org.apache.yoko.orb.OCI.TransportInfo; import org.apache.yoko.util.Assert; import org.apache.yoko.util.Cache; -import org.apache.yoko.util.Factory; import org.apache.yoko.util.Reference; import org.omg.BiDirPolicy.BOTH; import org.omg.CONV_FRAME.CodeSetContext; @@ -51,7 +50,7 @@ import static java.util.logging.Level.FINEST; import static org.apache.yoko.logging.VerboseLogging.CONN_OUT_LOG; import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_LATIN_1; -import static org.apache.yoko.orb.OB.CodeSetUtil.getCodeConverters; +import static org.apache.yoko.orb.OB.CodeSetUtil.getNegotiatedCodecs; import static org.apache.yoko.orb.OB.SendingContextRuntimes.SENDING_CONTEXT_RUNTIME; import static org.apache.yoko.orb.exceptions.Transients.ACTIVE_CONNECTION_MANAGEMENT; import static org.omg.CORBA.CompletionStatus.COMPLETED_NO; @@ -63,12 +62,12 @@ final class GIOPClient extends Client { @Override public String toString() { - return super.toString() + " to " + connector_.get_info() + " -- " + connection_; + return super.toString() + " to " + connector.get_info() + " -- " + connection_; } - protected ORBInstance orbInstance_; + private ORBInstance orbInstance; - protected final Connector connector_; + private final Connector connector; /** A lazily final field pointing (eventually) to the single connection for the lifetime of this object */ private GIOPConnection connection_; @@ -76,24 +75,24 @@ public String toString() { private Reference connectionRef; /** Codesets SC */ - protected ServiceContext codeSetSC_; + private ServiceContext codeSetSC; - protected ServiceContext codeBaseSC_; + private ServiceContext codeBaseSC; - protected boolean bidirWorker_; // is the worker bidir? + private final boolean bidirWorker; // is the worker bidir? - private boolean destroy_; // True if destroy() was called + private boolean destroyCalled; // True if destroy() was called // ---------------------------------------------------------------------- // GIOPClient private and protected member implementations // ---------------------------------------------------------------------- - // uses the prepopulated connector_ (not connected) to do a lookup, + // uses the prepopulated connector (not connected) to do a lookup, // checking if a bidir connection alias exists... it returns it if // it does and returns null otherwise - protected GIOPConnection find_bidir_worker() { + private GIOPConnection findBidirWorker() { try { - for (POAManager poaManager : orbInstance_.getPOAManagerFactory().list()) { + for (POAManager poaManager : orbInstance.getPOAManagerFactory().list()) { for (Server aServSeq : ((POAManager_impl) poaManager)._OB_getServerManager().getServers()) { GIOPConnection conn = ((GIOPServer) aServSeq)._OB_getGIOPServerStarter().getMatchingConnection(connectorInfo()); if (conn != null) return conn; @@ -108,8 +107,8 @@ protected GIOPConnection find_bidir_worker() { // a new worker is created, with the timeout specified as second // parameter. // - protected synchronized GIOPConnection getWorker(boolean create, final int timeout) { - if (destroy_) + private synchronized GIOPConnection getWorker(boolean create, final int timeout) { + if (destroyCalled) throw ACTIVE_CONNECTION_MANAGEMENT.create(); if (connection_ == null) @@ -135,16 +134,11 @@ protected synchronized GIOPConnection getWorker(boolean create, final int timeou } private synchronized void reuseOrCreateOutboundConnection(boolean create, final int timeout) { - Cache connCache = orbInstance_.getOutboundConnectionCache(); + Cache connCache = orbInstance.getOutboundConnectionCache(); if (create) { - connectionRef = connCache.getOrCreate(connector_.get_info(), new Factory() { - @Override - public GIOPConnection create() { - return createOutboundConnection(timeout); - } - }); + connectionRef = connCache.getOrCreate(connector.get_info(), () -> createOutboundConnection(timeout)); } else { - connectionRef = connCache.get(connector_.get_info()); + connectionRef = connCache.get(connector.get_info()); } connCache.clean(); connection_ = connectionRef.get(); @@ -154,7 +148,7 @@ public GIOPConnection create() { // service requests so we need to set ourselves up as a // server (to correct map the OAInterfaces) // - if (bidirWorker_) + if (bidirWorker) connection_.activateServerSide(); } @@ -162,7 +156,7 @@ private synchronized void reuseInboundConnection() { // // first attempt to locate a reusable bidir connection // - connection_ = find_bidir_worker(); + connection_ = findBidirWorker(); if (connection_ == null) return; @@ -176,23 +170,23 @@ private GIOPConnectionThreaded createOutboundConnection(int t) { // Trace connection attempt if (CONN_OUT_LOG.isLoggable(FINE)) { String timeout = t >= 0 ? t + "ms" : "none"; - String msg = String.format("trying to establish connection: %s timeout: %s", connector_, timeout); + String msg = String.format("trying to establish connection: %s timeout: %s", connector, timeout); CONN_OUT_LOG.fine(msg); } // // Create new transport, using the connector // - // For symetry reasons, GIOPClientStarterThreaded should also be + // For symmetry reasons, GIOPClientStarterThreaded should also be // added, even though these classes only have a trivial // functionality. Or perhaps the GIOPClientStarterThreaded tries to - // connect() in the backgound? Just an idea... + // connect() in the background? Just an idea... // Transport transport; if (t >= 0) { - transport = connector_.connect_timeout(t); + transport = connector.connect_timeout(t); // // Was there a timeout? @@ -200,7 +194,7 @@ private GIOPConnectionThreaded createOutboundConnection(int t) { if (transport == null) throw new NO_RESPONSE("Connection timeout", 0, COMPLETED_NO); } else { - transport = connector_.connect(); + transport = connector.connect(); Assert.ensure(transport != null); } @@ -208,17 +202,17 @@ private GIOPConnectionThreaded createOutboundConnection(int t) { // Create new worker // Assert.ensure(concurrencyModel == Threaded); - return new GIOPConnectionThreaded(orbInstance_, transport, this); + return new GIOPConnectionThreaded(orbInstance, transport, this); } // initialize internal service contexts private void initServiceContexts() { - if (codeSetSC_ == null) { + if (codeSetSC == null) { CodeSetContext ctx = new CodeSetContext(); - CodeConverters conv = codeConverters(); + CodecPair codecs = codecs(); - ctx.char_data = conv.outputCharConverter == null ? ISO_LATIN_1.id : conv.outputCharConverter.getDestinationCodeSet().id; - ctx.wchar_data = conv.outputWcharConverter == null ? orbInstance_.getNativeWcs() : conv.outputWcharConverter.getDestinationCodeSet().id; + ctx.char_data = codecs.charCodec.getCodeSetInfo().id; + ctx.wchar_data = codecs.wcharCodec.getCodeSetInfo().id; // Create encapsulation for CONV_FRAME::CodeSetContext try (YokoOutputStream outCSC = new YokoOutputStream()) { @@ -227,13 +221,13 @@ private void initServiceContexts() { // Create service context containing the // CONV_FRAME::CodeSetContext encapsulation - codeSetSC_ = new ServiceContext(); - codeSetSC_.context_id = CodeSets.value; + codeSetSC = new ServiceContext(); + codeSetSC.context_id = CodeSets.value; - codeSetSC_.context_data = outCSC.copyWrittenBytes(); + codeSetSC.context_data = outCSC.copyWrittenBytes(); } } - if (codeBaseSC_ == null) codeBaseSC_ = SENDING_CONTEXT_RUNTIME; + if (codeBaseSC == null) codeBaseSC = SENDING_CONTEXT_RUNTIME; // NOTE: We don't initialize the INVOCATION_POLICIES service context // here because the list of policies can change from one invocation to // the next. Instead, we need to get the policies and build the @@ -242,20 +236,20 @@ private void initServiceContexts() { GIOPClient(ORBInstance orbInstance, Connector connector, int concModel, - CodeConverters conv, boolean bidirEnable) { + CodecPair conv, boolean bidirEnable) { super(concModel, conv); - orbInstance_ = orbInstance; - connector_ = connector; + this.orbInstance = orbInstance; + this.connector = connector; connection_ = null; - destroy_ = false; - bidirWorker_ = bidirEnable; + destroyCalled = false; + bidirWorker = bidirEnable; } /** Destroy the client */ public synchronized void destroy() { - if (destroy_) return; + if (destroyCalled) return; try (Reference closeMe = connectionRef) { - destroy_ = true; + destroyCalled = true; } } @@ -270,24 +264,24 @@ public ServiceContexts getAMIRouterContexts() { initServiceContexts(); // return the list - return ServiceContexts.unmodifiable(codeSetSC_); + return ServiceContexts.unmodifiable(codeSetSC); } /** Get all profiles that are usable with this client */ public ProfileInfo[] getUsableProfiles(IOR ior, Policy[] policies) { // Get all profiles usable for the connector List profileInfos = new ArrayList<>(); - for (ProfileInfo anAll : connector_.get_usable_profiles(ior, policies)) { - CodeConverters conv = getCodeConverters(orbInstance_, anAll); + for (ProfileInfo anAll : connector.get_usable_profiles(ior, policies)) { + CodecPair conv = getNegotiatedCodecs(orbInstance, anAll); // Filter out profiles which would require a different code converter - if (codeConverters().equals(conv)) profileInfos.add(anAll); + if (codecs().equals(conv)) profileInfos.add(anAll); } - return profileInfos.toArray(new ProfileInfo[profileInfos.size()]); + return profileInfos.toArray(new ProfileInfo[0]); } /** Get the OCI Connector info */ public ConnectorInfo connectorInfo() { - return connector_.get_info(); + return connector.get_info(); } /** Get the OCI Transport info */ @@ -320,13 +314,13 @@ public DowncallEmitter startDowncall(Downcall down, OutputStreamHolder out) { byte major = down.profileInfo().major; byte minor = down.profileInfo().minor; if (!connection.isRequestSent() && (major > 1 || minor >= 1)) { - if (CONN_OUT_LOG.isLoggable(FINEST)) CONN_OUT_LOG.finest("sending transmission code sets: \n" + codeConverters()); + if (CONN_OUT_LOG.isLoggable(FINEST)) CONN_OUT_LOG.finest("sending transmission code sets: \n" + codecs()); - Assert.ensure(codeSetSC_ != null); - down.addToRequestContexts(codeSetSC_); + Assert.ensure(codeSetSC != null); + down.addToRequestContexts(codeSetSC); - Assert.ensure(codeBaseSC_ != null); - down.addToRequestContexts(codeBaseSC_); + Assert.ensure(codeBaseSC != null); + down.addToRequestContexts(codeBaseSC); } // @@ -345,10 +339,10 @@ public DowncallEmitter startDowncall(Downcall down, OutputStreamHolder out) { } ProfileInfo profileInfo = down.profileInfo(); - out.value = new YokoOutputStream(Buffer.createWriteBuffer(12).padAll(), codeConverters(), GiopVersion.get(profileInfo.major, profileInfo.minor)); + out.value = new YokoOutputStream(Buffer.createWriteBuffer(12).padAll(), codecs(), GiopVersion.get(profileInfo.major, profileInfo.minor)); // Create GIOP outgoing message - GIOPOutgoingMessage outgoing = new GIOPOutgoingMessage(orbInstance_, out.value, profileInfo); + GIOPOutgoingMessage outgoing = new GIOPOutgoingMessage(orbInstance, out.value, profileInfo); // Write header if (down.operation().equals("_locate")) @@ -369,7 +363,7 @@ public boolean matches(Client other) { if (!!!(other instanceof GIOPClient)) return false; GIOPClient that = (GIOPClient) other; - return this.connector_.equal(that.connector_) && this.codeConverters().equals(that.codeConverters()); + return this.connector.equal(that.connector) && this.codecs().equals(that.codecs()); } /** Force connection establishment */ diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java index b7977725e..2db9e94be 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java @@ -132,7 +132,7 @@ abstract class GIOPConnection extends Connection implements DowncallEmitter, Upc int upcallsInProgress_ = 0; /** code converters used by the connection */ - private CodeConverters codeConverters_ = null; + private CodecPair codecs_ = null; /** maximum GIOP version encountered during message transactions */ final Version giopVersion_ = new Version((byte) 0, (byte) 0); @@ -164,12 +164,12 @@ synchronized boolean canSendCloseConnection() { /** read the codeset information from the service contexts */ private void readCodeConverters(ServiceContexts contexts) { - if (codeConverters_ != null) return; + if (codecs_ != null) return; ServiceContext csSC = contexts.get(CodeSets.value); if (csSC == null) return; CodeSetContext csCtx = CodeSetUtil.extractCodeSetContext(csSC); - this.codeConverters_ = CodeConverters.create(csCtx.char_data, csCtx.wchar_data); + this.codecs_ = CodecPair.create(csCtx.char_data, csCtx.wchar_data); if (CONN_IN_LOG.isLoggable(Level.FINEST)) { String msg = String.format("receiving transmission code sets%nchar code set: %s%nwchar code set: %s", @@ -331,7 +331,7 @@ private synchronized Upcall processRequest(GIOPIncomingMessage msg) { // Parse the service contexts for various codeset info readCodeConverters(contexts); - in._OB_codeConverters(codeConverters_, GiopVersion.get(version.major, version.minor)); + in.setCodecsAndGiopVersion(codecs_, GiopVersion.get(version.major, version.minor)); // read in the peer's sending context runtime object assignSendingContextRuntime(in, contexts); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/UTF8Writer.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/UTF8Writer.java deleted file mode 100644 index c30cd778a..000000000 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/UTF8Writer.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2025 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -import org.apache.yoko.io.WriteBuffer; - -final class UTF8Writer extends CodeSetWriter { - // This actually encodes CESU-8, which differs from UTF-8 only in the encoding of surrogates - private static final char MAX_16_BIT = Character.MAX_VALUE; - public void write_char(WriteBuffer writeBuffer, char v) { - if (v < 0x80) { - // Direct mapping (7 bits) for characters < 0x80 - writeBuffer.writeByte(v); - } else if (v < 0x800) { - // encode as 2 bytes (110xxxxx 10xxxxxx) - writeBuffer.writeByte((v >>> 6) | 0xc0); - writeBuffer.writeByte((v & 0x3f) | 0x80); - } else { - // encode as 3 bytes (1110xxxx 10xxxxxx 10xxxxxx) - writeBuffer.writeByte((v >>> 12) | 0xe0); - writeBuffer.writeByte(((v >>> 6) & 0x3f) | 0x80); - writeBuffer.writeByte((v & 0x3f) | 0x80); - } - } - - public void write_wchar(WriteBuffer writeBuffer, char v) { - write_char(writeBuffer, v); - } - - public int count_wchar(char value) { - if (value < 0x80) - return 1; - else if (value < 0x800) - return 2; - else - return 3; - } -} diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/UnresolvedException.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/UnresolvedException.java index c1b9df216..98835c869 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/UnresolvedException.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/UnresolvedException.java @@ -38,7 +38,7 @@ public class UnresolvedException extends UnknownException { private static final Logger LOGGER = Logger.getLogger(UnresolvedException.class.getName()); private final UNKNOWN ex; private final byte[] data; - private final CodeConverters converters; + private final CodecPair converters; private final CodeBase sendingContextRuntime; private final String codebase; @@ -48,7 +48,7 @@ public class UnresolvedException extends UnknownException { super.minor = ex.minor; this.ex = ex; this.data = data; - this.converters = is._OB_codeConverters(); + this.converters = is.getCodecs(); this.sendingContextRuntime = is.__getSendingContextRuntime(); this.codebase = is.__getCodeBase(); } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java index 0722e1ee7..1077e9f83 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java @@ -155,7 +155,7 @@ public YokoInputStream input() { public void createOutputStream(int offset) { final GiopVersion giopVersion = GiopVersion.get(profileInfo_.major, profileInfo_.minor); - out_ = new YokoOutputStream(createWriteBuffer(offset).padAll(), in_._OB_codeConverters(), giopVersion); + out_ = new YokoOutputStream(createWriteBuffer(offset).padAll(), in_.getCodecs(), giopVersion); } public YokoInputStream preUnmarshal() { @@ -198,7 +198,7 @@ public YokoOutputStream preMarshal() throws LocationForward { addUnsentConnectionServiceContexts(); upcallReturn_.upcallBeginReply(this, replyContexts); } else { - out_ = new YokoOutputStream(in_._OB_codeConverters(), GiopVersion.get(profileInfo_.major, profileInfo_.minor)); + out_ = new YokoOutputStream(in_.getCodecs(), GiopVersion.get(profileInfo_.major, profileInfo_.minor)); } out_._OB_ORBInstance(this.orbInstance()); if (out_ != null) out_.setTimeout(timeout); @@ -278,8 +278,8 @@ public void setSystemException(SystemException ex) { private static void createUnknownExceptionServiceContexts(UnknownException ex, ServiceContexts replyContexts) { final Throwable t = ex.originalEx; try (CmsfOverride o = CmsfThreadLocal.override()) { - CodeConverters codeConverters = CodeConverters.createForWcharWriteOnly(); - try (YokoOutputStream os = new YokoOutputStream(codeConverters, GIOP1_2)) { + CodecPair codecs = CodecPair.createForWcharWriteOnly(); + try (YokoOutputStream os = new YokoOutputStream(codecs, GIOP1_2)) { os._OB_writeEndian(); os.write_value(t, Throwable.class); ServiceContext sc = new ServiceContext(UnknownExceptionInfo.value, os.copyWrittenBytes()); diff --git a/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java b/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java index fb66e0443..980f7d7fb 100644 --- a/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java +++ b/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java @@ -21,7 +21,7 @@ import org.apache.yoko.orb.CORBA.YokoInputStream; import org.apache.yoko.orb.CORBA.ORB; import org.apache.yoko.orb.CORBA.YokoOutputStream; -import org.apache.yoko.orb.OB.CodeConverters; +import org.apache.yoko.orb.OB.CodecPair; import org.apache.yoko.orb.OB.ORBInstance; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.params.ParameterizedTest; @@ -194,8 +194,8 @@ static Stream unicodeTestStrings() { static YokoOutputStream newUtfSpecificOutputStream() { ORB orb = (ORB) ORB.init((String[]) null, null); ORBInstance orbInst = orb._OB_ORBInstance(); - CodeConverters codeConverters = CodeConverters.create(orbInst, UTF_8.id, UTF_16.id); - return new YokoOutputStream(codeConverters, GIOP1_2); + CodecPair codecs = CodecPair.create(UTF_8.id, UTF_16.id); + return new YokoOutputStream(codecs, GIOP1_2); } @ParameterizedTest(name = "{0}") diff --git a/yoko-verify/src/test/java/org/apache/yoko/orb/OB/ConversionWidthsTest.java b/yoko-verify/src/test/java/org/apache/yoko/orb/OB/ConversionWidthsTest.java deleted file mode 100644 index ed73812a2..000000000 --- a/yoko-verify/src/test/java/org/apache/yoko/orb/OB/ConversionWidthsTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -import org.junit.jupiter.api.Test; - -import java.nio.charset.StandardCharsets; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class ConversionWidthsTest { - static final char[] testData = { '\u0000', '\u007f', '\u0080', '\u07ff', '\u0800', '\uffff' }; - - @Test - public void testUTF8ConversionWidths() { - UTF8Writer writer = new UTF8Writer(); - for (char c: testData) { - assertEquals(StandardCharsets.UTF_8.encode(Character.toString(c)).remaining(), writer.count_wchar(c), - () -> String.format("Mismatch width for character '\\u%04x'", (int)c)); - } - } -} diff --git a/yoko-verify/src/test/java/org/apache/yoko/orb/OB/TestCharMapConversions.java b/yoko-verify/src/test/java/org/apache/yoko/orb/OB/TestCharMapConversions.java deleted file mode 100644 index a4287d723..000000000 --- a/yoko-verify/src/test/java/org/apache/yoko/orb/OB/TestCharMapConversions.java +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright 2019 IBM Corporation and others. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an \"AS IS\" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package org.apache.yoko.orb.OB; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.util.BitSet; -import java.util.EnumMap; - -import static org.apache.yoko.orb.OB.CharMapInfo.CM_IDENTITY; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_2; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_3; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_4; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_5; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_7; -import static org.apache.yoko.orb.OB.CharMapInfo.CM_8859_9; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; - -/** - * This test was developed from an older implementation of CharMapInfo and its now deleted adjunct "database" class. - * This was done to ensure that none of the character conversions was changed during refactoring. - * - * The values tested may be incorrect, since this test was developed to preserve behaviour. - * The reader is encouraged to correct any errors found and document them here. - */ -public class TestCharMapConversions { - private static final EnumMap auditLog = new EnumMap<>(CharMapInfo.class); - - @BeforeClass - public static void clearAudit() { - for (CharMapInfo cmi: CharMapInfo.values()) auditLog.put(cmi, new BitSet()); - } - - private static void logCharTested(CharMapInfo cmi, int otherChar) { - auditLog.get(cmi).set(otherChar); - } - - @AfterClass - public static void checkAllCasesWereCovered() { - // every enum member should have been tested with every possible character - BitSet expected = new BitSet(); - expected.set(Character.MIN_VALUE, Character.MAX_VALUE); - expected.set(Character.MAX_VALUE); - for (CharMapInfo cmi : CharMapInfo.values()) { - BitSet actual = auditLog.get(cmi); - actual.xor(expected); - assertThat(cmi + " should have had all its char conversions tested", actual, is(new BitSet())); - } - } - - private void assertConversion(CharMapInfo cmi, int otherChar, int javaChar) { - logCharTested(cmi, otherChar); - String msg = String.format("%s char %x should map to Java char %x", cmi, otherChar, javaChar); - assertThat(msg, cmi.convertToJava((char)otherChar), is((char)javaChar)); - if (javaChar == 0) return; - msg = String.format("Java char %x should map to %s char %x", javaChar, cmi, otherChar); - assertThat(msg, cmi.convertFromJava((char)javaChar), is((char)otherChar)); - } - - private void assertNoConversion(CharMapInfo cmi) { - assertNoConversion(cmi, Character.MIN_VALUE, Character.MAX_VALUE); - } - - private void assertNoConversionBefore(CharMapInfo cmi, int limit) { - assertNoConversion(cmi, Character.MIN_VALUE, limit - 1); - } - - private void assertNoConversionAfter(CharMapInfo cmi, int limit) { - assertNoConversion(cmi, limit + 1, Character.MAX_VALUE); - } - - private void assertNoConversion(CharMapInfo cmi, int startChar, int endChar) { - for (int i = startChar; i <= endChar; i++) { - logCharTested(cmi, i); - String msg = String.format("%s char %x should map to Java char %x", cmi, i, i); - assertThat(msg, cmi.convertToJava((char) i), is((char) i)); - final int i2 = cmi.convertFromJava((char) i); - if (i2 < startChar) { - // just check that javaChar2 converts to i again - msg = String.format("%s char %x should map to Java char %x", cmi, i2, i); - assertThat(msg, cmi.convertToJava((char) i2), is((char) i)); - } else { - msg = String.format("Java char %x should map to %s char %x", i, cmi, i); - assertThat(msg, i2, is(i)); - } - } - } - - - @Test - public void test1() { - assertNoConversion(CM_IDENTITY); - } - - @Test - public void test2() { - assertNoConversionBefore(CM_8859_2, 0x00a1); - assertConversion(CM_8859_2, 0x00a1, 0x0104); - assertConversion(CM_8859_2, 0x00a2, 0x02d8); - assertConversion(CM_8859_2, 0x00a3, 0x0141); - assertConversion(CM_8859_2, 0x00a4, 0x00a4); - assertConversion(CM_8859_2, 0x00a5, 0x013d); - assertConversion(CM_8859_2, 0x00a6, 0x015a); - assertConversion(CM_8859_2, 0x00a7, 0x00a7); - assertConversion(CM_8859_2, 0x00a8, 0x00a8); - assertConversion(CM_8859_2, 0x00a9, 0x0160); - assertConversion(CM_8859_2, 0x00aa, 0x015e); - assertConversion(CM_8859_2, 0x00ab, 0x0164); - assertConversion(CM_8859_2, 0x00ac, 0x0179); - assertConversion(CM_8859_2, 0x00ad, 0x00ad); - assertConversion(CM_8859_2, 0x00ae, 0x017d); - assertConversion(CM_8859_2, 0x00af, 0x017b); - assertConversion(CM_8859_2, 0x00b0, 0x00b0); - assertConversion(CM_8859_2, 0x00b1, 0x0105); - assertConversion(CM_8859_2, 0x00b2, 0x02db); - assertConversion(CM_8859_2, 0x00b3, 0x0142); - assertConversion(CM_8859_2, 0x00b4, 0x00b4); - assertConversion(CM_8859_2, 0x00b5, 0x013e); - assertConversion(CM_8859_2, 0x00b6, 0x015b); - assertConversion(CM_8859_2, 0x00b7, 0x02c7); - assertConversion(CM_8859_2, 0x00b8, 0x00b8); - assertConversion(CM_8859_2, 0x00b9, 0x0161); - assertConversion(CM_8859_2, 0x00ba, 0x015f); - assertConversion(CM_8859_2, 0x00bb, 0x0165); - assertConversion(CM_8859_2, 0x00bc, 0x017a); - assertConversion(CM_8859_2, 0x00bd, 0x02dd); - assertConversion(CM_8859_2, 0x00be, 0x017e); - assertConversion(CM_8859_2, 0x00bf, 0x017c); - assertConversion(CM_8859_2, 0x00c0, 0x0154); - assertConversion(CM_8859_2, 0x00c1, 0x00c1); - assertConversion(CM_8859_2, 0x00c2, 0x00c2); - assertConversion(CM_8859_2, 0x00c3, 0x0102); - assertConversion(CM_8859_2, 0x00c4, 0x00c4); - assertConversion(CM_8859_2, 0x00c5, 0x0139); - assertConversion(CM_8859_2, 0x00c6, 0x0106); - assertConversion(CM_8859_2, 0x00c7, 0x00c7); - assertConversion(CM_8859_2, 0x00c8, 0x010c); - assertConversion(CM_8859_2, 0x00c9, 0x00c9); - assertConversion(CM_8859_2, 0x00ca, 0x0118); - assertConversion(CM_8859_2, 0x00cb, 0x00cb); - assertConversion(CM_8859_2, 0x00cc, 0x011a); - assertConversion(CM_8859_2, 0x00cd, 0x00cd); - assertConversion(CM_8859_2, 0x00ce, 0x00ce); - assertConversion(CM_8859_2, 0x00cf, 0x010e); - assertConversion(CM_8859_2, 0x00d0, 0x0110); - assertConversion(CM_8859_2, 0x00d1, 0x0143); - assertConversion(CM_8859_2, 0x00d2, 0x0147); - assertConversion(CM_8859_2, 0x00d3, 0x00d3); - assertConversion(CM_8859_2, 0x00d4, 0x00d4); - assertConversion(CM_8859_2, 0x00d5, 0x0150); - assertConversion(CM_8859_2, 0x00d6, 0x00d6); - assertConversion(CM_8859_2, 0x00d7, 0x00d7); - assertConversion(CM_8859_2, 0x00d8, 0x0158); - assertConversion(CM_8859_2, 0x00d9, 0x016e); - assertConversion(CM_8859_2, 0x00da, 0x00da); - assertConversion(CM_8859_2, 0x00db, 0x0170); - assertConversion(CM_8859_2, 0x00dc, 0x00dc); - assertConversion(CM_8859_2, 0x00dd, 0x00dd); - assertConversion(CM_8859_2, 0x00de, 0x0162); - assertConversion(CM_8859_2, 0x00df, 0x00df); - assertConversion(CM_8859_2, 0x00e0, 0x0155); - assertConversion(CM_8859_2, 0x00e1, 0x00e1); - assertConversion(CM_8859_2, 0x00e2, 0x00e2); - assertConversion(CM_8859_2, 0x00e3, 0x0103); - assertConversion(CM_8859_2, 0x00e4, 0x00e4); - assertConversion(CM_8859_2, 0x00e5, 0x013a); - assertConversion(CM_8859_2, 0x00e6, 0x0107); - assertConversion(CM_8859_2, 0x00e7, 0x00e7); - assertConversion(CM_8859_2, 0x00e8, 0x010d); - assertConversion(CM_8859_2, 0x00e9, 0x00e9); - assertConversion(CM_8859_2, 0x00ea, 0x0119); - assertConversion(CM_8859_2, 0x00eb, 0x00eb); - assertConversion(CM_8859_2, 0x00ec, 0x011b); - assertConversion(CM_8859_2, 0x00ed, 0x00ed); - assertConversion(CM_8859_2, 0x00ee, 0x00ee); - assertConversion(CM_8859_2, 0x00ef, 0x010f); - assertConversion(CM_8859_2, 0x00f0, 0x0111); - assertConversion(CM_8859_2, 0x00f1, 0x0144); - assertConversion(CM_8859_2, 0x00f2, 0x0148); - assertConversion(CM_8859_2, 0x00f3, 0x00f3); - assertConversion(CM_8859_2, 0x00f4, 0x00f4); - assertConversion(CM_8859_2, 0x00f5, 0x0151); - assertConversion(CM_8859_2, 0x00f6, 0x00f6); - assertConversion(CM_8859_2, 0x00f7, 0x00f7); - assertConversion(CM_8859_2, 0x00f8, 0x0159); - assertConversion(CM_8859_2, 0x00f9, 0x016f); - assertConversion(CM_8859_2, 0x00fa, 0x00fa); - assertConversion(CM_8859_2, 0x00fb, 0x0171); - assertConversion(CM_8859_2, 0x00fc, 0x00fc); - assertConversion(CM_8859_2, 0x00fd, 0x00fd); - assertConversion(CM_8859_2, 0x00fe, 0x0163); - assertConversion(CM_8859_2, 0x00ff, 0x02d9); - assertNoConversionAfter(CM_8859_2, 0x00ff); - } - - @Test - public void test3() { - assertNoConversionBefore(CM_8859_3, 0x00a1); - assertConversion(CM_8859_3, 0x00a1, 0x0126); - assertConversion(CM_8859_3, 0x00a2, 0x02d8); - assertConversion(CM_8859_3, 0x00a3, 0x00a3); - assertConversion(CM_8859_3, 0x00a4, 0x00a4); - assertConversion(CM_8859_3, 0x00a5, 0x0000); - assertConversion(CM_8859_3, 0x00a6, 0x0124); - assertConversion(CM_8859_3, 0x00a7, 0x00a7); - assertConversion(CM_8859_3, 0x00a8, 0x00a8); - assertConversion(CM_8859_3, 0x00a9, 0x0130); - assertConversion(CM_8859_3, 0x00aa, 0x015e); - assertConversion(CM_8859_3, 0x00ab, 0x011e); - assertConversion(CM_8859_3, 0x00ac, 0x0134); - assertConversion(CM_8859_3, 0x00ad, 0x00ad); - assertConversion(CM_8859_3, 0x00ae, 0x0000); - assertConversion(CM_8859_3, 0x00af, 0x017b); - assertConversion(CM_8859_3, 0x00b0, 0x00b0); - assertConversion(CM_8859_3, 0x00b1, 0x0127); - assertConversion(CM_8859_3, 0x00b2, 0x00b2); - assertConversion(CM_8859_3, 0x00b3, 0x00b3); - assertConversion(CM_8859_3, 0x00b4, 0x00b4); - assertConversion(CM_8859_3, 0x00b5, 0x00b5); - assertConversion(CM_8859_3, 0x00b6, 0x0125); - assertConversion(CM_8859_3, 0x00b7, 0x00b7); - assertConversion(CM_8859_3, 0x00b8, 0x00b8); - assertConversion(CM_8859_3, 0x00b9, 0x0131); - assertConversion(CM_8859_3, 0x00ba, 0x015f); - assertConversion(CM_8859_3, 0x00bb, 0x011f); - assertConversion(CM_8859_3, 0x00bc, 0x0135); - assertConversion(CM_8859_3, 0x00bd, 0x00bd); - assertConversion(CM_8859_3, 0x00be, 0x0000); - assertConversion(CM_8859_3, 0x00bf, 0x017c); - assertConversion(CM_8859_3, 0x00c0, 0x00c0); - assertConversion(CM_8859_3, 0x00c1, 0x00c1); - assertConversion(CM_8859_3, 0x00c2, 0x00c2); - assertConversion(CM_8859_3, 0x00c3, 0x0000); - assertConversion(CM_8859_3, 0x00c4, 0x00c4); - assertConversion(CM_8859_3, 0x00c5, 0x010a); - assertConversion(CM_8859_3, 0x00c6, 0x0108); - assertConversion(CM_8859_3, 0x00c7, 0x00c7); - assertConversion(CM_8859_3, 0x00c8, 0x00c8); - assertConversion(CM_8859_3, 0x00c9, 0x00c9); - assertConversion(CM_8859_3, 0x00ca, 0x00ca); - assertConversion(CM_8859_3, 0x00cb, 0x00cb); - assertConversion(CM_8859_3, 0x00cc, 0x00cc); - assertConversion(CM_8859_3, 0x00cd, 0x00cd); - assertConversion(CM_8859_3, 0x00ce, 0x00ce); - assertConversion(CM_8859_3, 0x00cf, 0x00cf); - assertConversion(CM_8859_3, 0x00d0, 0x0000); - assertConversion(CM_8859_3, 0x00d1, 0x00d1); - assertConversion(CM_8859_3, 0x00d2, 0x00d2); - assertConversion(CM_8859_3, 0x00d3, 0x00d3); - assertConversion(CM_8859_3, 0x00d4, 0x00d4); - assertConversion(CM_8859_3, 0x00d5, 0x0120); - assertConversion(CM_8859_3, 0x00d6, 0x00d6); - assertConversion(CM_8859_3, 0x00d7, 0x00d7); - assertConversion(CM_8859_3, 0x00d8, 0x011c); - assertConversion(CM_8859_3, 0x00d9, 0x00d9); - assertConversion(CM_8859_3, 0x00da, 0x00da); - assertConversion(CM_8859_3, 0x00db, 0x00db); - assertConversion(CM_8859_3, 0x00dc, 0x00dc); - assertConversion(CM_8859_3, 0x00dd, 0x016c); - assertConversion(CM_8859_3, 0x00de, 0x015c); - assertConversion(CM_8859_3, 0x00df, 0x00df); - assertConversion(CM_8859_3, 0x00e0, 0x00e0); - assertConversion(CM_8859_3, 0x00e1, 0x00e1); - assertConversion(CM_8859_3, 0x00e2, 0x00e2); - assertConversion(CM_8859_3, 0x00e3, 0x0000); - assertConversion(CM_8859_3, 0x00e4, 0x00e4); - assertConversion(CM_8859_3, 0x00e5, 0x010b); - assertConversion(CM_8859_3, 0x00e6, 0x0109); - assertConversion(CM_8859_3, 0x00e7, 0x00e7); - assertConversion(CM_8859_3, 0x00e8, 0x00e8); - assertConversion(CM_8859_3, 0x00e9, 0x00e9); - assertConversion(CM_8859_3, 0x00ea, 0x00ea); - assertConversion(CM_8859_3, 0x00eb, 0x00eb); - assertConversion(CM_8859_3, 0x00ec, 0x00ec); - assertConversion(CM_8859_3, 0x00ed, 0x00ed); - assertConversion(CM_8859_3, 0x00ee, 0x00ee); - assertConversion(CM_8859_3, 0x00ef, 0x00ef); - assertConversion(CM_8859_3, 0x00f0, 0x0000); - assertConversion(CM_8859_3, 0x00f1, 0x00f1); - assertConversion(CM_8859_3, 0x00f2, 0x00f2); - assertConversion(CM_8859_3, 0x00f3, 0x00f3); - assertConversion(CM_8859_3, 0x00f4, 0x00f4); - assertConversion(CM_8859_3, 0x00f5, 0x0121); - assertConversion(CM_8859_3, 0x00f6, 0x00f6); - assertConversion(CM_8859_3, 0x00f7, 0x00f7); - assertConversion(CM_8859_3, 0x00f8, 0x011d); - assertConversion(CM_8859_3, 0x00f9, 0x00f9); - assertConversion(CM_8859_3, 0x00fa, 0x00fa); - assertConversion(CM_8859_3, 0x00fb, 0x00fb); - assertConversion(CM_8859_3, 0x00fc, 0x00fc); - assertConversion(CM_8859_3, 0x00fd, 0x016d); - assertConversion(CM_8859_3, 0x00fe, 0x015d); - assertConversion(CM_8859_3, 0x00ff, 0x02d9); - assertNoConversionAfter(CM_8859_3, 0x00ff); - } - - @Test - public void test4() { - assertNoConversionBefore(CM_8859_4, 0x00a1); - assertConversion(CM_8859_4, 0x00a1, 0x0104); - assertConversion(CM_8859_4, 0x00a2, 0x0138); - assertConversion(CM_8859_4, 0x00a3, 0x0156); - assertConversion(CM_8859_4, 0x00a4, 0x00a4); - assertConversion(CM_8859_4, 0x00a5, 0x0128); - assertConversion(CM_8859_4, 0x00a6, 0x013b); - assertConversion(CM_8859_4, 0x00a7, 0x00a7); - assertConversion(CM_8859_4, 0x00a8, 0x00a8); - assertConversion(CM_8859_4, 0x00a9, 0x0160); - assertConversion(CM_8859_4, 0x00aa, 0x0112); - assertConversion(CM_8859_4, 0x00ab, 0x0122); - assertConversion(CM_8859_4, 0x00ac, 0x0166); - assertConversion(CM_8859_4, 0x00ad, 0x00ad); - assertConversion(CM_8859_4, 0x00ae, 0x017d); - assertConversion(CM_8859_4, 0x00af, 0x00af); - assertConversion(CM_8859_4, 0x00b0, 0x00b0); - assertConversion(CM_8859_4, 0x00b1, 0x0105); - assertConversion(CM_8859_4, 0x00b2, 0x02db); - assertConversion(CM_8859_4, 0x00b3, 0x0157); - assertConversion(CM_8859_4, 0x00b4, 0x00b4); - assertConversion(CM_8859_4, 0x00b5, 0x0129); - assertConversion(CM_8859_4, 0x00b6, 0x013c); - assertConversion(CM_8859_4, 0x00b7, 0x02c7); - assertConversion(CM_8859_4, 0x00b8, 0x00b8); - assertConversion(CM_8859_4, 0x00b9, 0x0161); - assertConversion(CM_8859_4, 0x00ba, 0x0113); - assertConversion(CM_8859_4, 0x00bb, 0x0123); - assertConversion(CM_8859_4, 0x00bc, 0x0167); - assertConversion(CM_8859_4, 0x00bd, 0x014a); - assertConversion(CM_8859_4, 0x00be, 0x017e); - assertConversion(CM_8859_4, 0x00bf, 0x014b); - assertConversion(CM_8859_4, 0x00c0, 0x0100); - assertConversion(CM_8859_4, 0x00c1, 0x00c1); - assertConversion(CM_8859_4, 0x00c2, 0x00c2); - assertConversion(CM_8859_4, 0x00c3, 0x00c3); - assertConversion(CM_8859_4, 0x00c4, 0x00c4); - assertConversion(CM_8859_4, 0x00c5, 0x00c5); - assertConversion(CM_8859_4, 0x00c6, 0x00c6); - assertConversion(CM_8859_4, 0x00c7, 0x012e); - assertConversion(CM_8859_4, 0x00c8, 0x010c); - assertConversion(CM_8859_4, 0x00c9, 0x00c9); - assertConversion(CM_8859_4, 0x00ca, 0x0118); - assertConversion(CM_8859_4, 0x00cb, 0x00cb); - assertConversion(CM_8859_4, 0x00cc, 0x0116); - assertConversion(CM_8859_4, 0x00cd, 0x00cd); - assertConversion(CM_8859_4, 0x00ce, 0x00ce); - assertConversion(CM_8859_4, 0x00cf, 0x012a); - assertConversion(CM_8859_4, 0x00d0, 0x0110); - assertConversion(CM_8859_4, 0x00d1, 0x0145); - assertConversion(CM_8859_4, 0x00d2, 0x014c); - assertConversion(CM_8859_4, 0x00d3, 0x0136); - assertConversion(CM_8859_4, 0x00d4, 0x00d4); - assertConversion(CM_8859_4, 0x00d5, 0x00d5); - assertConversion(CM_8859_4, 0x00d6, 0x00d6); - assertConversion(CM_8859_4, 0x00d7, 0x00d7); - assertConversion(CM_8859_4, 0x00d8, 0x00d8); - assertConversion(CM_8859_4, 0x00d9, 0x0172); - assertConversion(CM_8859_4, 0x00da, 0x00da); - assertConversion(CM_8859_4, 0x00db, 0x00db); - assertConversion(CM_8859_4, 0x00dc, 0x00dc); - assertConversion(CM_8859_4, 0x00dd, 0x0168); - assertConversion(CM_8859_4, 0x00de, 0x016a); - assertConversion(CM_8859_4, 0x00df, 0x00df); - assertConversion(CM_8859_4, 0x00e0, 0x0101); - assertConversion(CM_8859_4, 0x00e1, 0x00e1); - assertConversion(CM_8859_4, 0x00e2, 0x00e2); - assertConversion(CM_8859_4, 0x00e3, 0x00e3); - assertConversion(CM_8859_4, 0x00e4, 0x00e4); - assertConversion(CM_8859_4, 0x00e5, 0x00e5); - assertConversion(CM_8859_4, 0x00e6, 0x00e6); - assertConversion(CM_8859_4, 0x00e7, 0x012f); - assertConversion(CM_8859_4, 0x00e8, 0x010d); - assertConversion(CM_8859_4, 0x00e9, 0x00e9); - assertConversion(CM_8859_4, 0x00ea, 0x0119); - assertConversion(CM_8859_4, 0x00eb, 0x00eb); - assertConversion(CM_8859_4, 0x00ec, 0x0117); - assertConversion(CM_8859_4, 0x00ed, 0x00ed); - assertConversion(CM_8859_4, 0x00ee, 0x00ee); - assertConversion(CM_8859_4, 0x00ef, 0x012b); - assertConversion(CM_8859_4, 0x00f0, 0x0111); - assertConversion(CM_8859_4, 0x00f1, 0x0146); - assertConversion(CM_8859_4, 0x00f2, 0x014d); - assertConversion(CM_8859_4, 0x00f3, 0x0137); - assertConversion(CM_8859_4, 0x00f4, 0x00f4); - assertConversion(CM_8859_4, 0x00f5, 0x00f5); - assertConversion(CM_8859_4, 0x00f6, 0x00f6); - assertConversion(CM_8859_4, 0x00f7, 0x00f7); - assertConversion(CM_8859_4, 0x00f8, 0x00f8); - assertConversion(CM_8859_4, 0x00f9, 0x0173); - assertConversion(CM_8859_4, 0x00fa, 0x00fa); - assertConversion(CM_8859_4, 0x00fb, 0x00fb); - assertConversion(CM_8859_4, 0x00fc, 0x00fc); - assertConversion(CM_8859_4, 0x00fd, 0x0169); - assertConversion(CM_8859_4, 0x00fe, 0x016b); - assertConversion(CM_8859_4, 0x00ff, 0x02d9); - assertNoConversionAfter(CM_8859_4, 0x00ff); - } - - @Test - public void test5() { - assertNoConversionBefore(CM_8859_5, 0x00a1); - assertConversion(CM_8859_5, 0x00a1, 0x0401); - assertConversion(CM_8859_5, 0x00a2, 0x0402); - assertConversion(CM_8859_5, 0x00a3, 0x0403); - assertConversion(CM_8859_5, 0x00a4, 0x0404); - assertConversion(CM_8859_5, 0x00a5, 0x0405); - assertConversion(CM_8859_5, 0x00a6, 0x0406); - assertConversion(CM_8859_5, 0x00a7, 0x0407); - assertConversion(CM_8859_5, 0x00a8, 0x0408); - assertConversion(CM_8859_5, 0x00a9, 0x0409); - assertConversion(CM_8859_5, 0x00aa, 0x040a); - assertConversion(CM_8859_5, 0x00ab, 0x040b); - assertConversion(CM_8859_5, 0x00ac, 0x040c); - assertConversion(CM_8859_5, 0x00ad, 0x00ad); - assertConversion(CM_8859_5, 0x00ae, 0x040e); - assertConversion(CM_8859_5, 0x00af, 0x040f); - assertConversion(CM_8859_5, 0x00b0, 0x0410); - assertConversion(CM_8859_5, 0x00b1, 0x0411); - assertConversion(CM_8859_5, 0x00b2, 0x0412); - assertConversion(CM_8859_5, 0x00b3, 0x0413); - assertConversion(CM_8859_5, 0x00b4, 0x0414); - assertConversion(CM_8859_5, 0x00b5, 0x0415); - assertConversion(CM_8859_5, 0x00b6, 0x0416); - assertConversion(CM_8859_5, 0x00b7, 0x0417); - assertConversion(CM_8859_5, 0x00b8, 0x0418); - assertConversion(CM_8859_5, 0x00b9, 0x0419); - assertConversion(CM_8859_5, 0x00ba, 0x041a); - assertConversion(CM_8859_5, 0x00bb, 0x041b); - assertConversion(CM_8859_5, 0x00bc, 0x041c); - assertConversion(CM_8859_5, 0x00bd, 0x041d); - assertConversion(CM_8859_5, 0x00be, 0x041e); - assertConversion(CM_8859_5, 0x00bf, 0x041f); - assertConversion(CM_8859_5, 0x00c0, 0x0420); - assertConversion(CM_8859_5, 0x00c1, 0x0421); - assertConversion(CM_8859_5, 0x00c2, 0x0422); - assertConversion(CM_8859_5, 0x00c3, 0x0423); - assertConversion(CM_8859_5, 0x00c4, 0x0424); - assertConversion(CM_8859_5, 0x00c5, 0x0425); - assertConversion(CM_8859_5, 0x00c6, 0x0426); - assertConversion(CM_8859_5, 0x00c7, 0x0427); - assertConversion(CM_8859_5, 0x00c8, 0x0428); - assertConversion(CM_8859_5, 0x00c9, 0x0429); - assertConversion(CM_8859_5, 0x00ca, 0x042a); - assertConversion(CM_8859_5, 0x00cb, 0x042b); - assertConversion(CM_8859_5, 0x00cc, 0x042c); - assertConversion(CM_8859_5, 0x00cd, 0x042d); - assertConversion(CM_8859_5, 0x00ce, 0x042e); - assertConversion(CM_8859_5, 0x00cf, 0x042f); - assertConversion(CM_8859_5, 0x00d0, 0x0430); - assertConversion(CM_8859_5, 0x00d1, 0x0431); - assertConversion(CM_8859_5, 0x00d2, 0x0432); - assertConversion(CM_8859_5, 0x00d3, 0x0433); - assertConversion(CM_8859_5, 0x00d4, 0x0434); - assertConversion(CM_8859_5, 0x00d5, 0x0435); - assertConversion(CM_8859_5, 0x00d6, 0x0436); - assertConversion(CM_8859_5, 0x00d7, 0x0437); - assertConversion(CM_8859_5, 0x00d8, 0x0438); - assertConversion(CM_8859_5, 0x00d9, 0x0439); - assertConversion(CM_8859_5, 0x00da, 0x043a); - assertConversion(CM_8859_5, 0x00db, 0x043b); - assertConversion(CM_8859_5, 0x00dc, 0x043c); - assertConversion(CM_8859_5, 0x00dd, 0x043d); - assertConversion(CM_8859_5, 0x00de, 0x043e); - assertConversion(CM_8859_5, 0x00df, 0x043f); - assertConversion(CM_8859_5, 0x00e0, 0x0440); - assertConversion(CM_8859_5, 0x00e1, 0x0441); - assertConversion(CM_8859_5, 0x00e2, 0x0442); - assertConversion(CM_8859_5, 0x00e3, 0x0443); - assertConversion(CM_8859_5, 0x00e4, 0x0444); - assertConversion(CM_8859_5, 0x00e5, 0x0445); - assertConversion(CM_8859_5, 0x00e6, 0x0446); - assertConversion(CM_8859_5, 0x00e7, 0x0447); - assertConversion(CM_8859_5, 0x00e8, 0x0448); - assertConversion(CM_8859_5, 0x00e9, 0x0449); - assertConversion(CM_8859_5, 0x00ea, 0x044a); - assertConversion(CM_8859_5, 0x00eb, 0x044b); - assertConversion(CM_8859_5, 0x00ec, 0x044c); - assertConversion(CM_8859_5, 0x00ed, 0x044d); - assertConversion(CM_8859_5, 0x00ee, 0x044e); - assertConversion(CM_8859_5, 0x00ef, 0x044f); - assertConversion(CM_8859_5, 0x00f0, 0x2116); - assertConversion(CM_8859_5, 0x00f1, 0x0451); - assertConversion(CM_8859_5, 0x00f2, 0x0452); - assertConversion(CM_8859_5, 0x00f3, 0x0453); - assertConversion(CM_8859_5, 0x00f4, 0x0454); - assertConversion(CM_8859_5, 0x00f5, 0x0455); - assertConversion(CM_8859_5, 0x00f6, 0x0456); - assertConversion(CM_8859_5, 0x00f7, 0x0457); - assertConversion(CM_8859_5, 0x00f8, 0x0458); - assertConversion(CM_8859_5, 0x00f9, 0x0459); - assertConversion(CM_8859_5, 0x00fa, 0x045a); - assertConversion(CM_8859_5, 0x00fb, 0x045b); - assertConversion(CM_8859_5, 0x00fc, 0x045c); - assertConversion(CM_8859_5, 0x00fd, 0x00a7); - assertConversion(CM_8859_5, 0x00fe, 0x045e); - assertConversion(CM_8859_5, 0x00ff, 0x045f); - assertNoConversionAfter(CM_8859_5, 0x00ff); - } - - @Test - public void test7() { - assertNoConversionBefore(CM_8859_7, 0x00a1); - assertConversion(CM_8859_7, 0x00a1, 0x2018); - assertConversion(CM_8859_7, 0x00a2, 0x2019); - assertConversion(CM_8859_7, 0x00a3, 0x00a3); - assertConversion(CM_8859_7, 0x00a4, 0x0000); - assertConversion(CM_8859_7, 0x00a5, 0x0000); - assertConversion(CM_8859_7, 0x00a6, 0x00a6); - assertConversion(CM_8859_7, 0x00a7, 0x00a7); - assertConversion(CM_8859_7, 0x00a8, 0x00a8); - assertConversion(CM_8859_7, 0x00a9, 0x00a9); - assertConversion(CM_8859_7, 0x00aa, 0x0000); - assertConversion(CM_8859_7, 0x00ab, 0x00ab); - assertConversion(CM_8859_7, 0x00ac, 0x00ac); - assertConversion(CM_8859_7, 0x00ad, 0x00ad); - assertConversion(CM_8859_7, 0x00ae, 0x0000); - assertConversion(CM_8859_7, 0x00af, 0x2015); - assertConversion(CM_8859_7, 0x00b0, 0x00b0); - assertConversion(CM_8859_7, 0x00b1, 0x00b1); - assertConversion(CM_8859_7, 0x00b2, 0x00b2); - assertConversion(CM_8859_7, 0x00b3, 0x00b3); - assertConversion(CM_8859_7, 0x00b4, 0x0384); - assertConversion(CM_8859_7, 0x00b5, 0x0385); - assertConversion(CM_8859_7, 0x00b6, 0x0386); - assertConversion(CM_8859_7, 0x00b7, 0x00b7); - assertConversion(CM_8859_7, 0x00b8, 0x0388); - assertConversion(CM_8859_7, 0x00b9, 0x0389); - assertConversion(CM_8859_7, 0x00ba, 0x038a); - assertConversion(CM_8859_7, 0x00bb, 0x00bb); - assertConversion(CM_8859_7, 0x00bc, 0x038c); - assertConversion(CM_8859_7, 0x00bd, 0x00bd); - assertConversion(CM_8859_7, 0x00be, 0x038e); - assertConversion(CM_8859_7, 0x00bf, 0x038f); - assertConversion(CM_8859_7, 0x00c0, 0x0390); - assertConversion(CM_8859_7, 0x00c1, 0x0391); - assertConversion(CM_8859_7, 0x00c2, 0x0392); - assertConversion(CM_8859_7, 0x00c3, 0x0393); - assertConversion(CM_8859_7, 0x00c4, 0x0394); - assertConversion(CM_8859_7, 0x00c5, 0x0395); - assertConversion(CM_8859_7, 0x00c6, 0x0396); - assertConversion(CM_8859_7, 0x00c7, 0x0397); - assertConversion(CM_8859_7, 0x00c8, 0x0398); - assertConversion(CM_8859_7, 0x00c9, 0x0399); - assertConversion(CM_8859_7, 0x00ca, 0x039a); - assertConversion(CM_8859_7, 0x00cb, 0x039b); - assertConversion(CM_8859_7, 0x00cc, 0x039c); - assertConversion(CM_8859_7, 0x00cd, 0x039d); - assertConversion(CM_8859_7, 0x00ce, 0x039e); - assertConversion(CM_8859_7, 0x00cf, 0x039f); - assertConversion(CM_8859_7, 0x00d0, 0x03a0); - assertConversion(CM_8859_7, 0x00d1, 0x03a1); - assertConversion(CM_8859_7, 0x00d2, 0x0000); - assertConversion(CM_8859_7, 0x00d3, 0x03a3); - assertConversion(CM_8859_7, 0x00d4, 0x03a4); - assertConversion(CM_8859_7, 0x00d5, 0x03a5); - assertConversion(CM_8859_7, 0x00d6, 0x03a6); - assertConversion(CM_8859_7, 0x00d7, 0x03a7); - assertConversion(CM_8859_7, 0x00d8, 0x03a8); - assertConversion(CM_8859_7, 0x00d9, 0x03a9); - assertConversion(CM_8859_7, 0x00da, 0x03aa); - assertConversion(CM_8859_7, 0x00db, 0x03ab); - assertConversion(CM_8859_7, 0x00dc, 0x03ac); - assertConversion(CM_8859_7, 0x00dd, 0x03ad); - assertConversion(CM_8859_7, 0x00de, 0x03ae); - assertConversion(CM_8859_7, 0x00df, 0x03af); - assertConversion(CM_8859_7, 0x00e0, 0x03b0); - assertConversion(CM_8859_7, 0x00e1, 0x03b1); - assertConversion(CM_8859_7, 0x00e2, 0x03b2); - assertConversion(CM_8859_7, 0x00e3, 0x03b3); - assertConversion(CM_8859_7, 0x00e4, 0x03b4); - assertConversion(CM_8859_7, 0x00e5, 0x03b5); - assertConversion(CM_8859_7, 0x00e6, 0x03b6); - assertConversion(CM_8859_7, 0x00e7, 0x03b7); - assertConversion(CM_8859_7, 0x00e8, 0x03b8); - assertConversion(CM_8859_7, 0x00e9, 0x03b9); - assertConversion(CM_8859_7, 0x00ea, 0x03ba); - assertConversion(CM_8859_7, 0x00eb, 0x03bb); - assertConversion(CM_8859_7, 0x00ec, 0x03bc); - assertConversion(CM_8859_7, 0x00ed, 0x03bd); - assertConversion(CM_8859_7, 0x00ee, 0x03be); - assertConversion(CM_8859_7, 0x00ef, 0x03bf); - assertConversion(CM_8859_7, 0x00f0, 0x03c0); - assertConversion(CM_8859_7, 0x00f1, 0x03c1); - assertConversion(CM_8859_7, 0x00f2, 0x03c2); - assertConversion(CM_8859_7, 0x00f3, 0x03c3); - assertConversion(CM_8859_7, 0x00f4, 0x03c4); - assertConversion(CM_8859_7, 0x00f5, 0x03c5); - assertConversion(CM_8859_7, 0x00f6, 0x03c6); - assertConversion(CM_8859_7, 0x00f7, 0x03c7); - assertConversion(CM_8859_7, 0x00f8, 0x03c8); - assertConversion(CM_8859_7, 0x00f9, 0x03c9); - assertConversion(CM_8859_7, 0x00fa, 0x03ca); - assertConversion(CM_8859_7, 0x00fb, 0x03cb); - assertConversion(CM_8859_7, 0x00fc, 0x03cc); - assertConversion(CM_8859_7, 0x00fd, 0x03cd); - assertConversion(CM_8859_7, 0x00fe, 0x03ce); - assertNoConversionAfter(CM_8859_7, 0x00fe); - } - - @Test - public void test9() { - assertNoConversionBefore(CM_8859_9, 0x00d0); - assertConversion(CM_8859_9, 0x00d0, 0x011e); - assertConversion(CM_8859_9, 0x00d1, 0x00d1); - assertConversion(CM_8859_9, 0x00d2, 0x00d2); - assertConversion(CM_8859_9, 0x00d3, 0x00d3); - assertConversion(CM_8859_9, 0x00d4, 0x00d4); - assertConversion(CM_8859_9, 0x00d5, 0x00d5); - assertConversion(CM_8859_9, 0x00d6, 0x00d6); - assertConversion(CM_8859_9, 0x00d7, 0x00d7); - assertConversion(CM_8859_9, 0x00d8, 0x00d8); - assertConversion(CM_8859_9, 0x00d9, 0x00d9); - assertConversion(CM_8859_9, 0x00da, 0x00da); - assertConversion(CM_8859_9, 0x00db, 0x00db); - assertConversion(CM_8859_9, 0x00dc, 0x00dc); - assertConversion(CM_8859_9, 0x00dd, 0x0130); - assertConversion(CM_8859_9, 0x00de, 0x015e); - assertConversion(CM_8859_9, 0x00df, 0x00df); - assertConversion(CM_8859_9, 0x00e0, 0x00e0); - assertConversion(CM_8859_9, 0x00e1, 0x00e1); - assertConversion(CM_8859_9, 0x00e2, 0x00e2); - assertConversion(CM_8859_9, 0x00e3, 0x00e3); - assertConversion(CM_8859_9, 0x00e4, 0x00e4); - assertConversion(CM_8859_9, 0x00e5, 0x00e5); - assertConversion(CM_8859_9, 0x00e6, 0x00e6); - assertConversion(CM_8859_9, 0x00e7, 0x00e7); - assertConversion(CM_8859_9, 0x00e8, 0x00e8); - assertConversion(CM_8859_9, 0x00e9, 0x00e9); - assertConversion(CM_8859_9, 0x00ea, 0x00ea); - assertConversion(CM_8859_9, 0x00eb, 0x00eb); - assertConversion(CM_8859_9, 0x00ec, 0x00ec); - assertConversion(CM_8859_9, 0x00ed, 0x00ed); - assertConversion(CM_8859_9, 0x00ee, 0x00ee); - assertConversion(CM_8859_9, 0x00ef, 0x00ef); - assertConversion(CM_8859_9, 0x00f0, 0x011f); - assertConversion(CM_8859_9, 0x00f1, 0x00f1); - assertConversion(CM_8859_9, 0x00f2, 0x00f2); - assertConversion(CM_8859_9, 0x00f3, 0x00f3); - assertConversion(CM_8859_9, 0x00f4, 0x00f4); - assertConversion(CM_8859_9, 0x00f5, 0x00f5); - assertConversion(CM_8859_9, 0x00f6, 0x00f6); - assertConversion(CM_8859_9, 0x00f7, 0x00f7); - assertConversion(CM_8859_9, 0x00f8, 0x00f8); - assertConversion(CM_8859_9, 0x00f9, 0x00f9); - assertConversion(CM_8859_9, 0x00fa, 0x00fa); - assertConversion(CM_8859_9, 0x00fb, 0x00fb); - assertConversion(CM_8859_9, 0x00fc, 0x00fc); - assertConversion(CM_8859_9, 0x00fd, 0x0131); - assertConversion(CM_8859_9, 0x00fe, 0x015f); - assertNoConversionAfter(CM_8859_9, 0x00fe); - } -} From 86994a1338676b18c3041d0783c0a34764541ed1 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Wed, 4 Feb 2026 13:09:05 +0000 Subject: [PATCH 05/18] feat: use UTF-8 and UTF-16 codeset defaults Remove the yoko.orb.extended_wchar configuration property and improve default codeset selection for profiles without codeset components. IIOP 1.0 profiles now use ISO Latin 1, while IIOP 1.1+ profiles default to UTF-8. Changes: - Remove ORBInstance.extendedWchar field and extendedWchar() method - Remove yoko.orb.extended_wchar property parsing from ORBInstance constructor - Simplify CodeSetUtil.getCodeSetInfoFromComponents(): - Remove proprietary ISO Latin 1 / UCS-2 fallback for IIOP 1.0 - IIOP 1.0 profiles consistently return null (no components) - Add clarifying comment about IIOP 1.0 having no components - Improve CodeSetUtil.getCodeConverters() default behavior: - IIOP 1.0 profiles without components: ISO Latin 1 + default wchar - IIOP 1.1+ profiles without components: UTF-8 + default wchar - Set defaultWcs to UTF_16.id instead of 0 in ORB_impl Rationale: The extended_wchar configuration was a proprietary extension that allowed wchar/wstring support for IIOP 1.0 by assuming ISO Latin 1 for char and UCS-2 for wchar. This is no longer needed. This change adds a default wchar codeset for 1.0 that is backwards-compatible with the previous (optional) default wchar codeset. The default char codeset for 1.1+ is not UTF-8. This only kicks in if the IOR does not contain a codesets component. This is so iiop URLs can specify the version number as 1.2 and get a newer default char codeset for an initial lookup. The 1.1/1.2 protocols allow the codeset to be explicitly stated in a request. --- .../java/org/apache/yoko/orb/OB/CodeSetUtil.java | 14 +++++++------- .../java/org/apache/yoko/orb/OB/ORBInstance.java | 12 +----------- .../java/org/apache/yoko/orb/OBCORBA/ORB_impl.java | 2 +- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java index 2e84412ab..2105e5aba 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetUtil.java @@ -47,12 +47,8 @@ static CodeSetComponent createCodeSetComponent(final int native_codeset_id, fina } static CodeSetComponentInfo getCodeSetInfoFromComponents(ORBInstance orbInstance, ProfileInfo profileInfo) { - // For IIOP 1.0 use proprietary mechanism (ISOLATIN1 and UCS2), if configured. - if (profileInfo.major == 1 && profileInfo.minor == 0) { - if (!orbInstance.extendedWchar()) return null; - // proprietary codeset configured, so use ISO Latin 1 for char and UCS 2 for wchar - return new CodeSetComponentInfo(new CodeSetComponent(ISO_LATIN_1.id), new CodeSetComponent(UCS_2.id)); - } + // IIOP 1.0 profiles have no components + if (profileInfo.major == 1 && profileInfo.minor == 0) return null; // For IIOP 1.1 or newer extract codeset from profile return Stream.of(profileInfo.components) @@ -70,7 +66,11 @@ static CodecPair getNegotiatedCodecs(ORBInstance orbInstance, ProfileInfo profil final CodeSetComponentInfo info = getCodeSetInfoFromComponents(orbInstance, profileInfo); // defaults if no codeset profile was found in the IOR - if (info == null) return CodecPair.create(ISO_LATIN_1.id, orbInstance.getDefaultWcs()); + if (info == null) { + return profileInfo.major == 1 && profileInfo.minor == 0 ? + CodecPair.create(ISO_LATIN_1.id, orbInstance.getDefaultWcs()) : + CodecPair.create(UTF_8.id, orbInstance.getDefaultWcs()); + } CodeSetComponent client_cs = createCodeSetComponent(orbInstance.getNativeCs(), false); CodeSetComponent client_wcs = createCodeSetComponent(orbInstance.getNativeWcs(), true); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ORBInstance.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ORBInstance.java index 1e6ce6ee5..b1aaa4a63 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ORBInstance.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ORBInstance.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,6 @@ import java.util.Properties; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Phaser; import java.util.concurrent.atomic.AtomicBoolean; @@ -77,7 +76,6 @@ public final class ORBInstance { private UnknownExceptionStrategy unknownExceptionStrategy; private final URLRegistry urlRegistry; private final boolean useTypeCodeCache; - private final boolean extendedWchar; private OrbAsyncHandler asyncHandler; private final AtomicBoolean destroyCalled = new AtomicBoolean(); // True if destroy() was called @@ -150,10 +148,6 @@ public ORBInstance(ORB orb, String orbId, String serverID, String tcc = this.properties.getProperty("yoko.orb.use_type_code_cache"); useTypeCodeCache = tcc == null || !tcc.equals("false"); - // Support wchar/wstring for IIOP 1.0? - String extWchar = this.properties.getProperty("yoko.orb.extended_wchar"); - extendedWchar = extWchar != null && extWchar.equals("true"); - // get the number of AMI worker threads String amiWorkersStr = this.properties.getProperty("yoko.orb.ami_workers"); int amiWorkers = amiWorkersStr == null ? 1 : Math.max(1, parseInt(amiWorkersStr)); @@ -358,10 +352,6 @@ public boolean useTypeCodeCache() { return useTypeCodeCache; } - public boolean extendedWchar() { - return extendedWchar; - } - public OrbAsyncHandler getAsyncHandler() { return asyncHandler; } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java index 0ea89fc23..ee37f1554 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java @@ -858,7 +858,7 @@ private void setParameters(StringSeqHolder args, final Properties initialProps, int concModel = Client.Blocking; int nativeCs = UTF_8.id; int nativeWcs = UTF_16.id; - int defaultWcs = 0; + int defaultWcs = UTF_16.id; for (String key: properties.stringPropertyNames()) { if (!key.startsWith("yoko.orb.")) continue; From 3ef03df9583715dcab9100c633ed1fe4c8afdffd Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Thu, 5 Feb 2026 14:31:48 +0000 Subject: [PATCH 06/18] refactor: improve toString() for non-enum codecs --- .../src/main/java/org/apache/yoko/codecs/LatinCodec.java | 3 +++ .../src/main/java/org/apache/yoko/codecs/Utf8Codec.java | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java index fc9eacd28..86a02456e 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java @@ -125,4 +125,7 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(name); } + + @Override + public String toString() { return name; } } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java index 42a464091..16d53aa0b 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java @@ -225,4 +225,9 @@ private static int getUtf8Len(int codepoint) { @Override public int hashCode() { return name().hashCode(); } + + @Override + public String toString() { + return String.format("%s{h=0x%08x, l=0x%08x}", super.toString(), highSurrogate, lowSurrogate); + } } From db70309a2d1387502f5242a79bc329896082b634 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Thu, 5 Feb 2026 16:19:43 +0000 Subject: [PATCH 07/18] refactor: improve codec design and error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the codec system to better support collocated invocations, add an unspecified codec for error detection, and improve string marshalling error handling with better logging. BREAKING CHANGES: - Rename SimpleWcharCodec.NULL to COLLOCATED for clarity - Replace CharCodec constants with static factory methods: - NULL_CHAR_CODEC → getCollocatedCharCodec() - DEFAULT_CHAR_CODEC → getDefaultCharCodec() - Add getUnspecifiedCharCodec() for error detection Major changes: Codec architecture improvements: - Add SimpleWcharCodec.UNSPECIFIED codec that throws UnsupportedOperationException on all operations to detect improper codec usage - Add CharCodec.isStateless() method (default true) to identify stateful codecs - Add CodeSetInfo.COLLOCATED enum value for collocated invocations - Rename SimpleWcharCodec.NULL to COLLOCATED for better clarity - Update Utf8Codec.isStateless() to return false (stateful due to surrogate pairs) CodecPair improvements: - Make DEFAULT and COLLOCATED constants private - Add getCollocatedCodecs() factory method for collocated invocations - Improve createCopy() to avoid copying stateless codecs - Update createForWcharWriteOnly() to use UNSPECIFIED char codec instead of null - Reorder methods for better organization String marshalling improvements: - Add stringMarshallingError() helper method in YokoInputStream for consistent error reporting with context (string type, length, minor code) - Improve error messages for string/wstring reading with better context - Add bounds checking for negative string lengths - Wrap IndexOutOfBoundsException with proper MARSHAL exceptions - Improve logging with codec information in read/write operations Logging improvements: - Replace generic Logger with DATA_IN_LOG/DATA_OUT_LOG for verbose logging - Add codec information to string read/write log messages - Move WriteBuffer.recordLength() logging to use DATA_OUT_LOG - Remove logger parameter from WriteBuffer.recordLength() - Improve log message formatting with lambda expressions Code cleanup: - Update CollocatedClient to use getCollocatedCodecs() factory method - Remove unused logger imports - Improve code organization and readability - Add detailed javadoc for new methods The refactoring improves error detection, provides better diagnostic information for debugging marshalling issues, and makes the codec architecture more explicit about its intended usage patterns. --- .../org/apache/yoko/codecs/CharCodec.java | 7 +- .../apache/yoko/codecs/SimpleWcharCodec.java | 56 ++++++++++- .../org/apache/yoko/codecs/Utf8Codec.java | 6 +- .../org/apache/yoko/codecs/WcharCodec.java | 6 +- .../yoko/orb/CORBA/YokoInputStream.java | 98 ++++++++++--------- .../yoko/orb/CORBA/YokoOutputStream.java | 24 ++--- .../org/apache/yoko/orb/OB/CodeSetInfo.java | 1 + .../org/apache/yoko/orb/OB/CodecPair.java | 51 ++++++---- .../apache/yoko/orb/OB/CollocatedClient.java | 6 +- .../java/org/apache/yoko/io/WriteBuffer.java | 11 +-- 10 files changed, 170 insertions(+), 96 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java index a3333d24d..f5579b9e1 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java @@ -81,8 +81,9 @@ */ public interface CharCodec { @FunctionalInterface interface CharReader { char readChar(ReadBuffer in); } - CharCodec NULL_CHAR_CODEC = SimpleWcharCodec.NULL; - CharCodec DEFAULT_CHAR_CODEC = SimpleCharCodec.ISO_LATIN_1; + static CharCodec getCollocatedCharCodec() { return SimpleWcharCodec.COLLOCATED; } + static CharCodec getDefaultCharCodec() { return SimpleCharCodec.ISO_LATIN_1; } + static CharCodec getUnspecifiedCharCodec() { return SimpleWcharCodec.UNSPECIFIED; } /** * Get a char codec instance for the named Java charset. @@ -117,7 +118,7 @@ static CharCodec forRegistryId(int id) throws UnsupportedCharsetException { } String name(); - + default boolean isStateless() { return true; } CodeSetInfo getCodeSetInfo(); /** diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java index c532d1899..78eb4021f 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java @@ -95,8 +95,8 @@ public void writeLengthAndChar(char c, WriteBuffer out) { * It takes shortcuts because it exchanges data with another instance of the very same class. * e.g. it never writes any lengths or BOMs, so it never reads any lengths or BOMs. */ - NULL { - public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.NONE; } + COLLOCATED { + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.COLLOCATED; } public int octetCount(String s) { return 2 * s.length(); } @@ -111,5 +111,57 @@ public void writeLengthAndChar(char c, WriteBuffer out) { public void beginToWriteString(char c, WriteBuffer out) { out.writeChar(c); } public void writeLengthAndChar(char c, WriteBuffer out) { out.writeChar(c);} + }, + /** + * This codec is for use when no encoding is permitted. + */ + UNSPECIFIED { + @Override + public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.NONE; } + + @Override + public boolean isFixedWidth() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public int charSize() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public char readChar(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public int octetCount(char c) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public int octetCount(String s) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public int octetCountLengthsAndWchars(int numChars) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public void writeChar(char c, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public void assertNoBufferedCharData() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public boolean readFinished() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public boolean writeFinished() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public char readLengthAndChar(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public void writeLengthAndChar(char c, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public CharReader beginToReadString(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + + @Override + public void beginToWriteString(char firstChar, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } }; } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java index 16d53aa0b..a3b28c95a 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java @@ -176,7 +176,6 @@ private static void writeBytes(int codepoint, WriteBuffer out) { final int MASK_LAST_4_BITS = 0b0000_1111; final int MASK_LAST_5_BITS = 0b0001_1111; final int MASK_LAST_6_BITS = 0b0011_1111; - DATA_OUT_LOG.fine(() -> String.format("Encoding codepoint 0x%06X as %d bytes", codepoint, numBytes)); switch (numBytes) { case 1: // write out the byte as-is @@ -217,6 +216,9 @@ private static int getUtf8Len(int codepoint) { @Override public String name() { return "UTF-8"; } + @Override + public boolean isStateless() { return false; } + @Override public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.UTF_8; } @@ -228,6 +230,6 @@ private static int getUtf8Len(int codepoint) { @Override public String toString() { - return String.format("%s{h=0x%08x, l=0x%08x}", super.toString(), highSurrogate, lowSurrogate); + return String.format("%s{h=0x%04x, l=0x%04x}", super.toString(), (int)highSurrogate, (int)lowSurrogate); } } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java index 7bcd0b15d..6041e5602 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java @@ -25,9 +25,9 @@ import java.util.Optional; public interface WcharCodec extends CharCodec { - WcharCodec NULL_WCHAR_CODEC = SimpleWcharCodec.NULL; - WcharCodec DEFAULT_WCHAR_CODEC = SimpleWcharCodec.UTF_16; - static WcharCodec getDefault() { return DEFAULT_WCHAR_CODEC; } + static WcharCodec getCollocatedWcharCodec() { return SimpleWcharCodec.COLLOCATED; } + static WcharCodec getDefaultWcharCodec() { return SimpleWcharCodec.UTF_16; } + static WcharCodec getUnspecifiedWcharCodec() { return SimpleWcharCodec.UNSPECIFIED; } static WcharCodec forName(String name) { return Optional.of(name) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java index 71cfe7e12..9303f8ebe 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java @@ -55,7 +55,6 @@ import java.security.PrivilegedActionException; import java.util.Hashtable; import java.util.logging.Level; -import java.util.logging.Logger; import static java.security.AccessController.doPrivileged; import static java.util.stream.IntStream.range; @@ -150,8 +149,6 @@ import static org.omg.CORBA.TCKind.tk_union; final public class YokoInputStream extends InputStreamWithOffsets { - private static final Logger logger = DATA_IN_LOG; - private ORBInstance orbInstance; private final ReadBuffer readBuffer; @@ -197,8 +194,8 @@ private TypeCodeImpl checkCache(String id, int startPos, int length) { private TypeCode readTypeCodeImpl(Hashtable history, boolean isTopLevel) { int kind = read_ulong(); int oldPos = readBuffer.getPosition() - 4; - if (logger.isLoggable(Level.FINEST)) - logger.finest(String.format("Reading a TypeCode of kind %d from position 0x%x", kind, oldPos)); + if (DATA_IN_LOG.isLoggable(Level.FINEST)) + DATA_IN_LOG.finest(String.format("Reading a TypeCode of kind %d from position 0x%x", kind, oldPos)); TypeCodeImpl tc = null; if (kind == -1) { @@ -580,8 +577,8 @@ private TypeCode readTypeCodeImpl(Hashtable history, bool String id = read_string(); - if (logger.isLoggable(Level.FINE)) - logger.fine(String.format("Abstract interface typecode encapsulation length=0x%x id=%s", length, id)); + if (DATA_IN_LOG.isLoggable(Level.FINE)) + DATA_IN_LOG.fine(String.format("Abstract interface typecode encapsulation length=0x%x id=%s", length, id)); if (isTopLevel && cache != null) tc = checkCache(id, typePos, length); // may advance pos @@ -680,7 +677,7 @@ public boolean read_boolean() { try { int pos = readBuffer.getPosition(); byte b = readBuffer.readByte(); - if (logger.isLoggable(Level.FINEST)) logger.finest(String.format("Boolean value is 0x%08x from position 0x%x", b, pos)); + DATA_IN_LOG.finest(() -> String.format("Boolean value is 0x%02x from position 0x%x", b, pos)); return toBoolean(b); } catch (IndexOutOfBoundsException e) { throw newMarshalError((MinorReadBooleanOverflow), e); @@ -798,21 +795,17 @@ public String read_string() { // Number of octets (i.e. bytes) in the string (including the null terminator). // This may not be the same as the number of characters if encoding was done. - int byteCount = read_ulong(); - - if (byteCount == 0) throw newMarshalError(MinorReadStringZeroLength); - if (byteCount < 0) throw newMarshalError(MinorReadStringOverflow); - - if (readBuffer.available() < byteCount) { - if (logger.isLoggable(Level.FINE)) logger.fine(String.format("String length=0x%x %n%s", byteCount, readBuffer.dumpAllDataWithPosition())); - throw newMarshalError(MinorReadStringOverflow); - } + if (byteCount == 0) throw stringMarshallingError("string", byteCount, MinorReadStringZeroLength); + if (byteCount < 0) throw stringMarshallingError("string", byteCount, MinorReadStringOverflow); + if (readBuffer.available() < byteCount) throw stringMarshallingError("string", byteCount, MinorReadStringOverflow); // Java strings don't need null terminators, so our string length will be at most one less than the byte count StringBuilder sb = new StringBuilder(byteCount - 1); final CharCodec codec = codecs.charCodec; + DATA_IN_LOG.finest(() -> String.format("Reading string value of length=0x%x using codec %s", byteCount, codec)); + final int endPosition = readBuffer.getPosition() + byteCount - 1; try { @@ -835,58 +828,73 @@ public String read_string() { return sb.toString(); } + private MARSHAL stringMarshallingError(String stringDesc, int length, int minor) { + return stringMarshallingError(stringDesc, length, minor, null); + } + private MARSHAL stringMarshallingError(String stringDesc, int length, int minor, Exception e) { + MARSHAL marshal = null == e ? newMarshalError(minor): newMarshalError(minor, e); + DATA_IN_LOG.severe(String.format("Error reading %s of length %d: %s%n%s", + stringDesc, length, marshal.getMessage(), readBuffer.dumpAllDataWithPosition())); + return marshal; + } + public String read_wstring() { checkChunk(); - try { - switch (giopVersion) { - case GIOP1_0: - case GIOP1_1: - return read_wstring_pre_1_2(); - default: - return read_wstring_1_2(); - } - } catch (IndexOutOfBoundsException e) { - throw newMarshalError(MinorReadWStringOverflow, e); + switch (giopVersion) { + case GIOP1_0: + case GIOP1_1: + return read_wstring_pre_1_2(); + default: + return read_wstring_1_2(); } } private String read_wstring_pre_1_2() { // read the length of the string (in characters for GIOP 1.0/1.1) int numChars = read_ulong(); - if (logger.isLoggable(Level.FINE)) logger.fine(String.format("Reading GIOP 1.0 wstring of length %d chars", numChars)); // it is not legal in GIOP 1.0/1.1 for a string to be 0 in length... it MUST have a null terminator - if (numChars == 0) throw newMarshalError(MinorReadWStringZeroLength); + if (numChars == 0) throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadWStringZeroLength); // in GIOP 1.0/1.1, every char must be encoded as EXACTLY two bytes - if (readBuffer.available() < numChars * 2) throw newMarshalError(MinorReadWStringOverflow); + if (numChars < 0) throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadWStringOverflow); + if (readBuffer.available() < numChars * 2) throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadStringOverflow); + + final WcharCodec codec = codecs.wcharCodec; + DATA_IN_LOG.fine(() -> String.format("Reading GIOP 1.0 wstring of length %d chars using codec %s", numChars, codec)); // in GIOP 1.0/1.1, there is no BOM - use the endianness from context char[] tmp = new char[numChars]; - final WcharCodec wcharCodec = codecs.wcharCodec; - for (int i = 0; i < numChars; i++) tmp[i] = wcharCodec.readCharWithEndianFlag(readBuffer, swapBytes); - - // Check for terminating null wchar - if (0 != tmp[numChars - 1]) throw newMarshalError(MinorReadWStringNoTerminator); - - return new String(tmp, 0, numChars - 1); + try { + for (int i = 0; i < numChars; i++) tmp[i] = codec.readCharWithEndianFlag(readBuffer, swapBytes); + // Check for terminating null wchar + if (0 != tmp[numChars - 1]) throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadWStringNoTerminator); + return new String(tmp, 0, numChars - 1); + } catch (IndexOutOfBoundsException e) { + throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadWStringOverflow, e); + } } private String read_wstring_1_2() { // read the length of the string (in octets for GIOP 1.2+) int numOctets = read_ulong(); - if (readBuffer.available() < numOctets) throw newMarshalError(MinorReadWStringOverflow); + if (numOctets < 0) throw stringMarshallingError("GIOP 1.2 wstring", numOctets, MinorReadWStringOverflow); + if (readBuffer.available() < numOctets) throw stringMarshallingError("GIOP 1.2 wstring", numOctets, MinorReadWStringOverflow); + + WcharCodec codec = codecs.wcharCodec; + DATA_IN_LOG.fine(() -> String.format("Reading GIOP 1.2 wstring of length %d octets using codec %s", numOctets, codec)); - if (logger.isLoggable(Level.FINE)) logger.fine(String.format("Reading GIOP 1.2 wstring of length 0x%x octets", numOctets)); // In GIOP 1.2 there is no terminating null char, but there might be a BOM StringBuilder builder = new StringBuilder(numOctets / 2); final int endPosition = readBuffer.getPosition() + numOctets; // this method checks for and consumes a BOM if present, returning the appropriately endian char reader CharReader reader = codecs.wcharCodec.beginToReadString(readBuffer); - - while (readBuffer.getPosition() < endPosition) builder.append(reader.readChar(readBuffer)); - - return builder.toString(); + try { + while (readBuffer.getPosition() < endPosition) builder.append(reader.readChar(readBuffer)); + return builder.toString(); + } catch (IndexOutOfBoundsException e) { + throw stringMarshallingError("GIOP 1.2 wstring", numOctets, MinorReadWStringOverflow, e); + } } public void read_boolean_array(boolean[] value, int offset, int length) { @@ -1037,7 +1045,7 @@ public org.omg.CORBA.Object read_Object(@SuppressWarnings("rawtypes") Class expe } return createStub(getRMIStubClass(codebase, expectedType), impl._get_delegate()); } catch (IllegalAccessException | ClassNotFoundException | ClassCastException | PrivilegedActionException | InvocationTargetException ex) { - logger.log(Level.FINE, "Exception creating object stub", ex); + DATA_IN_LOG.log(Level.FINE, "Exception creating object stub", ex); throw newMarshalError(MinorLoadStub, ex); } } @@ -1051,7 +1059,7 @@ private org.omg.CORBA.Object createStub(Class stubClass, org.omg.CORBA.portab stub._set_delegate(delegate); return stub; } catch (InvocationTargetException | InstantiationException | IllegalAccessException | PrivilegedActionException ex) { - logger.log(Level.FINE, "Exception creating object stub", ex); + DATA_IN_LOG.log(Level.FINE, "Exception creating object stub", ex); throw newMarshalError(MinorLoadStub, ex); } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java index a2706f88b..b20b6e8d6 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java @@ -55,13 +55,13 @@ import java.util.HashMap; import java.util.Map; import java.util.Vector; -import java.util.logging.Logger; import static java.util.logging.Level.FINEST; import static org.apache.yoko.io.AlignmentBoundary.EIGHT_BYTE_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.FOUR_BYTE_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.NO_BOUNDARY; import static org.apache.yoko.io.AlignmentBoundary.TWO_BYTE_BOUNDARY; +import static org.apache.yoko.logging.VerboseLogging.DATA_OUT_LOG; import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_0; import static org.apache.yoko.util.MinorCodes.MinorIncompleteTypeCode; import static org.apache.yoko.util.MinorCodes.MinorLocalObject; @@ -108,8 +108,6 @@ import static org.omg.CORBA_2_4.TCKind._tk_local_interface; public final class YokoOutputStream extends OutputStream implements ValueOutputStream { - private static final Logger LOGGER = Logger.getLogger(YokoOutputStream.class.getName()); - private ORBInstance orbInstance; private final WriteBuffer writeBuffer; private final GiopVersion giopVersion; @@ -129,7 +127,7 @@ public final class YokoOutputStream extends OutputStream implements ValueOutputS private SimplyCloseable recordLength() { addCapacity(4, FOUR_BYTE_BOUNDARY); - return writeBuffer.recordLength(LOGGER); + return writeBuffer.recordLength(); } private void writeTypeCodeImpl(TypeCode tc, Map history) { @@ -150,7 +148,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { } } - if (LOGGER.isLoggable(FINEST)) LOGGER.finest("Writing a type code of type " + (tc == null ? null : tc.kind())); + if (DATA_OUT_LOG.isLoggable(FINEST)) DATA_OUT_LOG.finest("Writing a type code of type " + (tc == null ? null : tc.kind())); // For performance reasons, handle the primitive TypeCodes first switch (tc.kind().value()) { @@ -180,7 +178,7 @@ private void writeTypeCodeImpl(TypeCode tc, Map history) { if (indirectionPos != null) { write_long(-1); int offs = indirectionPos - writeBuffer.getPosition(); - LOGGER.finest("Writing an indirect type code for offset " + offs); + DATA_OUT_LOG.finest("Writing an indirect type code for offset " + offs); write_long(offs); } else { write_ulong(tc.kind().value()); @@ -499,8 +497,8 @@ public void write_double(double value) { } public void write_string(String value) { - LOGGER.finest("Writing string value " + value); final CharCodec codec = codecs.charCodec; + DATA_OUT_LOG.finest(() -> String.format("Writing string value %s using codec %s", value, codec)); final char[] arr = value.toCharArray(); if (codec.isFixedWidth()) { @@ -529,7 +527,6 @@ public void write_string(String value) { } public void write_wstring(String value) { - if (LOGGER.isLoggable(FINEST)) LOGGER.finest("Writing wstring value " + value); switch (giopVersion) { case GIOP1_0: case GIOP1_1: @@ -541,11 +538,12 @@ public void write_wstring(String value) { } private void write_wstring_pre_1_2(String value) { + final WcharCodec codec = codecs.wcharCodec; + DATA_OUT_LOG.finest(() -> String.format("Writing GIOP 1.0 wstring value %s using codec %s", value, codec)); // write the length of the string in chars write_ulong(value.length() + 1); // already 4-byte aligned, so just add the needed capacity for len 2-byte chars addCapacity(2*(value.length() + 1)); - final WcharCodec codec = codecs.wcharCodec; // now write all the characters for (int i = 0; i < value.length(); i++) codec.writeChar(value.charAt(i), writeBuffer); // and the null terminator @@ -556,12 +554,14 @@ private void write_wstring_1_2(String value) { // GIOP 1.2 encodes the length of the string in octets and does not require a null terminator // first deal with the empty string case if (value.isEmpty()) { + DATA_OUT_LOG.finest(() -> "Writing GIOP 1.2 empty string"); write_ulong(0); return; } // now we know there is a first character final WcharCodec codec = codecs.wcharCodec; int numOctets = codec.octetCount(value); + DATA_OUT_LOG.finest(() -> String.format("Writing GIOP 1.2 wstring value %s using codec %s using %d byte(s)", value, codec, numOctets)); // write the length of the string in octets write_ulong(numOctets); // add unaligned capacity @@ -663,7 +663,7 @@ public void write_double_array(double[] value, int offset, int length) { public void write_Object(org.omg.CORBA.Object value) { if (value == null) { - LOGGER.finest("Writing a null CORBA object value"); + DATA_OUT_LOG.finest("Writing a null CORBA object value"); IOR ior = new IOR(); ior.type_id = ""; ior.profiles = new TaggedProfile[0]; @@ -690,7 +690,7 @@ public void write_TypeCode(TypeCode t) { } public void write_any(Any value) { - LOGGER.finest("Writing an ANY value of type " + value.type().kind()); + DATA_OUT_LOG.finest("Writing an ANY value of type " + value.type().kind()); write_TypeCode(value.type()); value.write_value(this); } @@ -784,7 +784,7 @@ public void write_value(Serializable value, TypeCode tc, BoxedValueHelper helper public void write_InputStream(final org.omg.CORBA.portable.InputStream in, TypeCode tc) { try { - LOGGER.fine("writing a value of type " + tc.kind().value()); + DATA_OUT_LOG.fine("writing a value of type " + tc.kind().value()); switch (tc.kind().value()) { case _tk_null: diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java index 087c34565..e07c63835 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodeSetInfo.java @@ -50,6 +50,7 @@ public enum CodeSetInfo { NONE("none", 0x00000000), + COLLOCATED("collocated codeset for collocated invocations", 0xEEEEEEEE), ISO_LATIN_1("ISO 8859-1:1987; Latin Alphabet No. 1", 0x00010001, x0011), ISO_LATIN_2("ISO 8859-2:1987; Latin Alphabet No. 2", 0x00010002, x0012), ISO_LATIN_3("ISO 8859-3:1988; Latin Alphabet No. 3", 0x00010003, x0013), diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java index 7401931ff..6aa6d7076 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java @@ -22,9 +22,11 @@ import java.util.Objects; -import static org.apache.yoko.codecs.CharCodec.DEFAULT_CHAR_CODEC; -import static org.apache.yoko.codecs.CharCodec.NULL_CHAR_CODEC; -import static org.apache.yoko.codecs.WcharCodec.NULL_WCHAR_CODEC; +import static org.apache.yoko.codecs.CharCodec.getCollocatedCharCodec; +import static org.apache.yoko.codecs.CharCodec.getDefaultCharCodec; +import static org.apache.yoko.codecs.CharCodec.getUnspecifiedCharCodec; +import static org.apache.yoko.codecs.WcharCodec.getCollocatedWcharCodec; +import static org.apache.yoko.codecs.WcharCodec.getDefaultWcharCodec; // This class may look immutable, but charCodec can contain state (while reading/writing a surrogate pair from/to UTF-8) public final class CodecPair { @@ -32,8 +34,15 @@ public final class CodecPair { * The default codecs for GIOP 1.0. * TODO: consider whether we need an UNSUPPORTED wchar codec that throws exceptions for wchars */ - static final CodecPair DEFAULT = new CodecPair(DEFAULT_CHAR_CODEC, WcharCodec.DEFAULT_WCHAR_CODEC); - static final CodecPair COLLOCATED = new CodecPair(NULL_CHAR_CODEC, NULL_WCHAR_CODEC); + private static final CodecPair DEFAULT = new CodecPair(getDefaultCharCodec(), getDefaultWcharCodec()); + /** + * Codecs to use for collocated invocations + */ + static final CodecPair COLLOCATED = new CodecPair(getCollocatedCharCodec(), getCollocatedWcharCodec()); + + static CodecPair getCollocatedCodecs() { + return createCopy(COLLOCATED); + } public final CharCodec charCodec; public final WcharCodec wcharCodec; @@ -47,21 +56,8 @@ private CodecPair(CodecPair that) { this(that.charCodec.getInstanceOrCopy(), that.wcharCodec.getInstanceOrCopy()); } - public static CodecPair createCopy(CodecPair template) { - if (template == null) return DEFAULT; - if (template == DEFAULT) return DEFAULT; - if (template == COLLOCATED) return COLLOCATED; - return new CodecPair(template); - } - - public static CodecPair create(int tcs, int twcs) { - CharCodec cc = CharCodec.forRegistryId(tcs); - WcharCodec wc = WcharCodec.forRegistryId(twcs); - return new CodecPair(cc, wc); - } - - public static CodecPair createForWcharWriteOnly() { - return new CodecPair(null, WcharCodec.getDefault()); + private boolean isStateless() { + return charCodec.isStateless() && wcharCodec.isStateless(); } @Override @@ -79,4 +75,19 @@ public int hashCode() { public String toString() { return String.format("CodeConverters{%ncharCodec=%s%nwcharCodec=%s%n}", charCodec, wcharCodec); } + + public static CodecPair createCopy(CodecPair template) { + if (template == null) return createCopy(DEFAULT); + return template.isStateless() ? template : new CodecPair(template); + } + + public static CodecPair create(int tcs, int twcs) { + CharCodec cc = CharCodec.forRegistryId(tcs); + WcharCodec wc = WcharCodec.forRegistryId(twcs); + return new CodecPair(cc, wc); + } + + public static CodecPair createForWcharWriteOnly() { + return new CodecPair(getUnspecifiedCharCodec(), getDefaultWcharCodec()); + } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java index bdb9498d1..e04008be7 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java @@ -17,8 +17,6 @@ */ package org.apache.yoko.orb.OB; -import static org.apache.yoko.orb.OB.CodecPair.COLLOCATED; - import org.apache.yoko.orb.CORBA.YokoOutputStream; import org.apache.yoko.orb.CORBA.OutputStreamHolder; import org.apache.yoko.orb.IOP.ServiceContexts; @@ -28,6 +26,8 @@ import org.omg.CORBA.Policy; import org.omg.IOP.IOR; +import static org.apache.yoko.orb.OB.CodecPair.getCollocatedCodecs; + public final class CollocatedClient extends Client implements DowncallEmitter { // // My Server @@ -39,7 +39,7 @@ public final class CollocatedClient extends Client implements DowncallEmitter { // ---------------------------------------------------------------------- public CollocatedClient(CollocatedServer server, int concModel) { - super(concModel, COLLOCATED); + super(concModel, getCollocatedCodecs()); server_ = server; } diff --git a/yoko-util/src/main/java/org/apache/yoko/io/WriteBuffer.java b/yoko-util/src/main/java/org/apache/yoko/io/WriteBuffer.java index 567c02fdf..addd35a69 100644 --- a/yoko-util/src/main/java/org/apache/yoko/io/WriteBuffer.java +++ b/yoko-util/src/main/java/org/apache/yoko/io/WriteBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2025 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,10 @@ import java.io.InputStream; import java.io.InterruptedIOException; import java.util.Arrays; -import java.util.logging.Logger; import static java.lang.Double.doubleToRawLongBits; import static java.lang.Float.floatToRawIntBits; +import static org.apache.yoko.logging.VerboseLogging.DATA_OUT_LOG; @SuppressWarnings({"PointlessBitwiseExpression", "OctalInteger"}) public final class WriteBuffer extends Buffer { @@ -125,11 +125,10 @@ public WriteBuffer writeLong(long value) { /** * Leaves a 4 byte space to write a length. When {@link SimplyCloseable#close()} is called, * the number of intervening bytes is written as a length to the remembered location. - * @param logger the logger to use to log the operations - must not be null */ - public SimplyCloseable recordLength(final Logger logger) { + public SimplyCloseable recordLength() { final int lengthPosition = position; - logger.finest("Writing a gap value for a length at offset " + lengthPosition); + DATA_OUT_LOG.finest("Writing a gap value for a length at offset " + lengthPosition); pad(4); return () -> { @@ -139,7 +138,7 @@ public SimplyCloseable recordLength(final Logger logger) { data[lengthPosition + 1] = (byte) (length >> 020); data[lengthPosition + 2] = (byte) (length >> 010); data[lengthPosition + 3] = (byte) (length >> 000); - logger.finest("Wrote a length value of " + length + " at offset " + lengthPosition); + DATA_OUT_LOG.finest("Wrote a length value of " + length + " at offset " + lengthPosition); }; } From 3b6fdf32070c0ba545fa787fe9be953610b79421 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Thu, 5 Feb 2026 16:29:45 +0000 Subject: [PATCH 08/18] refactor: improve string writing log messages --- .../java/org/apache/yoko/orb/CORBA/YokoOutputStream.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java index b20b6e8d6..663baffc2 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java @@ -498,7 +498,7 @@ public void write_double(double value) { public void write_string(String value) { final CharCodec codec = codecs.charCodec; - DATA_OUT_LOG.finest(() -> String.format("Writing string value %s using codec %s", value, codec)); + DATA_OUT_LOG.finest(() -> String.format("Using codec %s to write string: \"%s\"", codec, value)); final char[] arr = value.toCharArray(); if (codec.isFixedWidth()) { @@ -539,7 +539,7 @@ public void write_wstring(String value) { private void write_wstring_pre_1_2(String value) { final WcharCodec codec = codecs.wcharCodec; - DATA_OUT_LOG.finest(() -> String.format("Writing GIOP 1.0 wstring value %s using codec %s", value, codec)); + DATA_OUT_LOG.finest(() -> String.format("Codec %s will use %d octets to write a GIOP 1.0 wstring: \"%s\"", codec, value.length() + 1, value)); // write the length of the string in chars write_ulong(value.length() + 1); // already 4-byte aligned, so just add the needed capacity for len 2-byte chars @@ -561,7 +561,7 @@ private void write_wstring_1_2(String value) { // now we know there is a first character final WcharCodec codec = codecs.wcharCodec; int numOctets = codec.octetCount(value); - DATA_OUT_LOG.finest(() -> String.format("Writing GIOP 1.2 wstring value %s using codec %s using %d byte(s)", value, codec, numOctets)); + DATA_OUT_LOG.finest(() -> String.format("Codec %s will use %d octets to write a GIOP 1.2 wstring: \"%s\"", codec, numOctets, value)); // write the length of the string in octets write_ulong(numOctets); // add unaligned capacity From 0dd72e59e71aac156ba677c32221b57549d61f3d Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Fri, 6 Feb 2026 11:46:48 +0000 Subject: [PATCH 09/18] refactor: improve collocated invocation codec init Fix collocated invocations to properly initialize output streams with codecs and GIOP version, and make COLLOCATED CodecPair constant private. Changes: - Update CollocatedClient.startDowncall() to create YokoOutputStream with: - Proper collocated codecs via CodecPair.getCollocatedCodecs() - Correct GIOP version from the profile info - Previously used no-arg constructor which defaulted to null codecs - Make CodecPair.COLLOCATED constant private (was package-private) - Forces use of getCollocatedCodecs() factory method - Ensures proper codec initialization for collocated calls - Add GiopVersion import to CollocatedClient - Remove unnecessary blank lines and comments in: - ClientManager (remove empty comment blocks) - POAManager_impl (remove extra blank line) Rationale: The previous code created YokoOutputStream with the no-arg constructor, which resulted in null codecs. This caused NullPointerException when trying to marshal strings in collocated invocations. The fix ensures that collocated invocations use proper codecs and GIOP version from the profile information. This completes the codec refactoring by ensuring all YokoOutputStream instances are properly initialized with codecs, preventing NPEs during string marshalling operations. --- .../src/main/java/org/apache/yoko/orb/OB/ClientManager.java | 2 -- yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java | 2 +- .../main/java/org/apache/yoko/orb/OB/CollocatedClient.java | 4 +++- .../org/apache/yoko/orb/OBPortableServer/POAManager_impl.java | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java index 6af66dc2e..ebd6a319f 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/ClientManager.java @@ -200,9 +200,7 @@ public synchronized Vector getClientProfilePairs(IOR ior, Pol // we can get into hang situations if we return a collocated server for an // inactive POA. This can happen with the RootPOA, which is generally not activated. if (local && mgr.get_state() == State.ACTIVE) { - // // Retrieve the CollocatedServer from the POAManager - // POAManager_impl manager = (POAManager_impl) mgr; CollocatedServer collocatedServer = manager._OB_getCollocatedServer(); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java index 6aa6d7076..567a5a326 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java @@ -38,7 +38,7 @@ public final class CodecPair { /** * Codecs to use for collocated invocations */ - static final CodecPair COLLOCATED = new CodecPair(getCollocatedCharCodec(), getCollocatedWcharCodec()); + private static final CodecPair COLLOCATED = new CodecPair(getCollocatedCharCodec(), getCollocatedWcharCodec()); static CodecPair getCollocatedCodecs() { return createCopy(COLLOCATED); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java index e04008be7..57da0acbd 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CollocatedClient.java @@ -21,6 +21,7 @@ import org.apache.yoko.orb.CORBA.OutputStreamHolder; import org.apache.yoko.orb.IOP.ServiceContexts; import org.apache.yoko.orb.OCI.ConnectorInfo; +import org.apache.yoko.orb.OCI.GiopVersion; import org.apache.yoko.orb.OCI.ProfileInfo; import org.apache.yoko.orb.OCI.TransportInfo; import org.omg.CORBA.Policy; @@ -89,7 +90,8 @@ public TransportInfo transportInfo() { // OutputStream for marshalling a request // public DowncallEmitter startDowncall(Downcall down, OutputStreamHolder out) { - out.value = new YokoOutputStream(); + GiopVersion gv = GiopVersion.get(down.profileInfo_.major, down.profileInfo_.minor); + out.value = new YokoOutputStream(CodecPair.getCollocatedCodecs(), gv); return this; } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAManager_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAManager_impl.java index 50c1abee5..45eaef275 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAManager_impl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAManager_impl.java @@ -1,5 +1,5 @@ /* - * Copyright 2024 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -236,7 +236,6 @@ public synchronized Acceptor[] get_acceptors() throws AdapterInactive { // Yoko internal functions // Application programs must not use these functions directly // ------------------------------------------------------------------ - POAManager_impl(ORBInstance orbInstance, POALocator poaLocator, String id, String adapterManagerId, Acceptor[] acceptors, From 6c8aa86612cdeecc59f1fac58f24ddb8471b1f66 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Fri, 6 Feb 2026 15:31:02 +0000 Subject: [PATCH 10/18] refactor: tighten up codecs package encapsulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all codec factory methods to new Codex class and rename WcharCodec methods to clarify GIOP version-specific behavior. BREAKING CHANGES: - CharCodec static factory methods moved to Codex class: - CharCodec.forName() → Codex.getCharCodec(String) - CharCodec.forRegistryId() → Codex.getCharCodec(int) - CharCodec.getDefaultCharCodec() → Codex.getDefaultCharCodec() - CharCodec.getCollocatedCharCodec() → Codex.getCollocatedCharCodec() - CharCodec.getUnspecifiedCharCodec() → removed (use Codex.getUnspecifiedWcharCodec()) - WcharCodec static factory methods moved to Codex class: - WcharCodec.forRegistryId() → Codex.getWcharCodec(int) - WcharCodec.getDefaultWcharCodec() → Codex.getDefaultWcharCodec() - WcharCodec.getCollocatedWcharCodec() → Codex.getCollocatedWcharCodec() - WcharCodec methods renamed to clarify GIOP version usage: - readCharWithEndianFlag() → readWchar_1_0() - writeChar() → writeWchar_1_0() - readLengthAndChar() → readWchar_1_2() - writeLengthAndChar() → writeWchar_1_2() - beginToReadString() → beginToReadWstring_1_2() - beginToWriteString() → beginToWriteWstring_1_2() - octetCount() → octetCountWstring_1_2() - octetCountLengthsAndWchars() → octetCountWchars_1_2() - charSize() → removed (always 2 bytes for GIOP 1.0/1.1) - CharCodec.CharReader → WcharCodec.WcharReader - readChar() → readWchar() - CharCodec/WcharCodec.getInstanceOrCopy() → duplicate() - CharCodec.isStateless() removed (now determined by duplicate() identity check) Changes: - Create new Codex class as central factory for all codec instances - Consolidates codec creation logic in one place - Provides factory methods for both CharCodec and WcharCodec - Includes getDefaultCodecs(GiopVersion) for version-specific defaults - Rename WcharCodec methods to include GIOP version suffixes - Makes it explicit which methods are for GIOP 1.0/1.1 vs 1.2 - Reduces confusion about when to use each method - Improves code readability at call sites - Move CharReader inner interface to WcharCodec as WcharReader - More accurate naming since it's only used for wide chars - Rename readChar() to readWchar() for consistency - Rename getInstanceOrCopy() to duplicate() in both interfaces - More intuitive name for creating concurrent-safe copies - Follows common naming patterns (e.g., ByteBuffer.duplicate()) - Remove isStateless() method from CharCodec - Now determined by identity check: codec.duplicate() == codec - Simplifies interface and implementation - Update CodecPair to use new Codex factory methods - Add GIOP_1_2_DEFAULT constant (uses UTF-8 for char codec) - Replace createForWcharWriteOnly() with getDefaultCodecs(GIOP1_2) - Simplify createCopy() using identity check for statefulness - Update all call sites in YokoInputStream/YokoOutputStream - Use renamed wchar methods with version suffixes - Remove hardcoded 2-byte size, use literal 2 for clarity - Update all test classes to use Codex factory methods - Replace CharCodec.forName() with Codex.getCharCodec() - Update test constructors to pass codec instances directly Rationale: The previous design scattered codec factory methods across CharCodec and WcharCodec interfaces, making it unclear where to find codec creation logic. The WcharCodec method names didn't indicate which GIOP version they were for, leading to potential confusion. This refactoring: 1. Centralizes all codec creation in the Codex class 2. Makes GIOP version requirements explicit in method names 3. Simplifies the codec interfaces by removing factory methods 4. Improves code clarity and maintainability 5. Provides version-specific default codec pairs --- .../org/apache/yoko/codecs/CharCodec.java | 49 ++-------- .../java/org/apache/yoko/codecs/Codex.java | 89 +++++++++++++++++++ .../apache/yoko/codecs/SimpleWcharCodec.java | 73 +++++++-------- .../org/apache/yoko/codecs/Utf8Codec.java | 5 +- .../java/org/apache/yoko/codecs/Util.java | 3 +- .../org/apache/yoko/codecs/WcharCodec.java | 61 ++++--------- .../yoko/orb/CORBA/YokoInputStream.java | 23 ++--- .../yoko/orb/CORBA/YokoOutputStream.java | 18 ++-- .../org/apache/yoko/orb/OB/CodecPair.java | 53 ++++++----- .../java/org/apache/yoko/orb/OB/Upcall.java | 2 +- .../yoko/codecs/AbstractLatinCodecTest.java | 2 +- .../yoko/codecs/AbstractSimpleCodecTest.java | 6 +- .../org/apache/yoko/codecs/IsoLatin1Test.java | 3 +- .../org/apache/yoko/codecs/UsAsciiTest.java | 2 +- .../org/apache/yoko/codecs/Utf16Test.java | 18 ++-- .../apache/yoko/codecs/Utf8InvalidTest.java | 2 +- .../java/org/apache/yoko/codecs/Utf8Test.java | 2 +- 17 files changed, 221 insertions(+), 190 deletions(-) create mode 100644 yoko-core/src/main/java/org/apache/yoko/codecs/Codex.java diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java index f5579b9e1..d03f4d5b8 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/CharCodec.java @@ -23,12 +23,7 @@ import org.apache.yoko.orb.OB.CodeSetInfo; import org.omg.CORBA.DATA_CONVERSION; -import java.nio.charset.Charset; -import java.nio.charset.IllegalCharsetNameException; -import java.nio.charset.UnsupportedCharsetException; - import static org.apache.yoko.codecs.LatinCodec.getLatinCodec; -import static org.apache.yoko.codecs.Util.getUnicodeCodec; import static org.apache.yoko.util.MinorCodes.MinorUTF8Encoding; import static org.apache.yoko.util.MinorCodes.MinorUTF8Overflow; import static org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE; @@ -80,45 +75,9 @@ *

*/ public interface CharCodec { - @FunctionalInterface interface CharReader { char readChar(ReadBuffer in); } - static CharCodec getCollocatedCharCodec() { return SimpleWcharCodec.COLLOCATED; } - static CharCodec getDefaultCharCodec() { return SimpleCharCodec.ISO_LATIN_1; } - static CharCodec getUnspecifiedCharCodec() { return SimpleWcharCodec.UNSPECIFIED; } - - /** - * Get a char codec instance for the named Java charset. - * - * @param name the name of the Java charset for which a codec is required - * @return an instance of the appropriate char codec - * @throws IllegalCharsetNameException if the provided name is not a valid charset name - * @throws IllegalArgumentException if the provided name is null - * @throws UnsupportedCharsetException if the named charset is not supported - */ - static CharCodec forName(String name) throws IllegalCharsetNameException, IllegalArgumentException, UnsupportedCharsetException { - // fastest result: directly named unicode codec - CharCodec result = getUnicodeCodec(name); - if (null != result) return result; - // next see if it is an alias for a unicode codec - Charset charset = Charset.forName(name); - result = getUnicodeCodec(charset.name()); - if (null != result) return result; - // the only other codecs currently supported are the Latin ones - return getLatinCodec(charset); - } - - static CharCodec forRegistryId(int id) throws UnsupportedCharsetException { - CodeSetInfo csi = CodeSetInfo.forRegistryId(id); - if (null == csi) throw new UnsupportedCharsetException(String.format("Unknown registry id: 0x%08x", id)); - switch (csi) { - case UTF_16: return SimpleWcharCodec.UTF_16; - case UTF_8: return new Utf8Codec(); - case ISO_LATIN_1: return SimpleCharCodec.ISO_LATIN_1; - default: return LatinCodec.getLatinCodec(csi); // throws if unknown - } - } String name(); - default boolean isStateless() { return true; } + CodeSetInfo getCodeSetInfo(); /** @@ -178,6 +137,8 @@ default void assertNoBufferedCharData() throws DATA_CONVERSION { /** Check whether the last character was not a high surrogate. */ default boolean writeFinished() { return true; } - /** Provides an identical object that can be used concurrently with this one */ - default CharCodec getInstanceOrCopy() { return this; } + /** + * Provides an identical object that can be used concurrently with this one + */ + default CharCodec duplicate() { return this; } } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Codex.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Codex.java new file mode 100644 index 000000000..be2a2f021 --- /dev/null +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Codex.java @@ -0,0 +1,89 @@ +/* + * Copyright 2026 IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an \"AS IS\" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.apache.yoko.codecs; + +import org.apache.yoko.orb.OB.CodeSetInfo; + +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Optional; + +import static org.apache.yoko.codecs.LatinCodec.getLatinCodec; +import static org.apache.yoko.codecs.SimpleWcharCodec.UTF_16; +import static org.apache.yoko.codecs.Util.getUnicodeCharCodec; + +public enum Codex { + ; + + public static CharCodec getCollocatedCharCodec() { return SimpleWcharCodec.COLLOCATED; } + + public static CharCodec getDefaultCharCodec() { return SimpleCharCodec.ISO_LATIN_1; } + + /** + * Get a char codec instance for the named Java charset. + * + * @param charsetName the charsetName of the Java charset for which a codec is required + * @return an instance of the appropriate char codec + * @throws IllegalCharsetNameException if the provided charsetName is not a valid charset charsetName + * @throws IllegalArgumentException if the provided charsetName is null + * @throws UnsupportedCharsetException if the named charset is not supported + */ + public static CharCodec getCharCodec(String charsetName) throws IllegalCharsetNameException, IllegalArgumentException, UnsupportedCharsetException { + // fastest result: directly named unicode codec + CharCodec result = getUnicodeCharCodec(charsetName); + if (null != result) return result; + // next see if it is an alias for a unicode codec + Charset charset = Charset.forName(charsetName); + result = getUnicodeCharCodec(charset.name()); + if (null != result) return result; + // the only other codecs currently supported are the Latin ones + return getLatinCodec(charset); + } + + public static CharCodec getCharCodec(int id) throws UnsupportedCharsetException { + CodeSetInfo csi = CodeSetInfo.forRegistryId(id); + if (null == csi) throw new UnsupportedCharsetException(String.format("Unknown registry id: 0x%08x", id)); + switch (csi) { + case UTF_8: return new Utf8Codec(); + case ISO_LATIN_1: return SimpleCharCodec.ISO_LATIN_1; + default: return LatinCodec.getLatinCodec(csi); // throws if unknown + } + } + + public static WcharCodec getCollocatedWcharCodec() { return SimpleWcharCodec.COLLOCATED; } + + public static WcharCodec getDefaultWcharCodec() { return UTF_16; } + + public static WcharCodec getUnspecifiedWcharCodec() { return SimpleWcharCodec.UNSPECIFIED; } + + public static WcharCodec getWcharCodec(String charsetName) { + if (charsetName == null) throw new NullPointerException(); + if ("UTF-16".equalsIgnoreCase(charsetName)) return UTF_16; + if ("UTF-16".equalsIgnoreCase(Charset.forName(charsetName).name())) return UTF_16; + throw new UnsupportedCharsetException(charsetName + " not supported for wchar"); + } + + public static WcharCodec getWcharCodec(int twcsId) { + if (CodeSetInfo.UTF_16.id == twcsId) return UTF_16; + String message = Optional.ofNullable(CodeSetInfo.forRegistryId(twcsId)) + .map(info -> String.format("Charset %s unsupported for wchar", info.name())) + .orElse(String.format("Unknown registry id 0x%08x unsupported for wchar", twcsId)); + throw new UnsupportedCharsetException(message); + } +} diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java index 78eb4021f..abc7ddcab 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/SimpleWcharCodec.java @@ -27,22 +27,22 @@ import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR; import static org.apache.yoko.codecs.Util.ZERO_WIDTH_NO_BREAK_SPACE; -enum SimpleWcharCodec implements WcharCodec { +enum SimpleWcharCodec implements WcharCodec, CharCodec { UTF_16 { public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.UTF_16; } - public int octetCount(String s) { - if (s.startsWith(""+ZERO_WIDTH_NO_BREAK_SPACE)) return 2 * (s.length() + 1); - return 2 * s.length(); + public int octetCountWstring_1_2(String s) { + boolean noBom = s.isEmpty() || s.charAt(0) != ZERO_WIDTH_NO_BREAK_SPACE; + return noBom ? 2 * s.length() : 2 * (s.length() + 1); } - public int octetCountLengthsAndWchars(int numChars) { return 3 * numChars; } + public int octetCountWchars_1_2(int numChars) { return 3 * numChars; } - public char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes) { + public char readWchar_1_0(ReadBuffer in, boolean swapBytes) { return swapBytes ? in.readChar_LE() : in.readChar(); } - public char readLengthAndChar(ReadBuffer in) { + public char readWchar_1_2(ReadBuffer in) { byte len = in.readByte(); switch (len) { case 2: @@ -64,7 +64,7 @@ public char readLengthAndChar(ReadBuffer in) { } } - public CharReader beginToReadString(ReadBuffer in) { + public WcharReader beginToReadWstring_1_2(ReadBuffer in) { if (in.isComplete()) return ReadBuffer::readChar; switch (in.readChar()) { case BYTE_ORDER_MARKER: return ReadBuffer::readChar; @@ -74,14 +74,14 @@ public CharReader beginToReadString(ReadBuffer in) { } } - public void beginToWriteString(char c, WriteBuffer out) { + public void beginToWriteWstring_1_2(char c, WriteBuffer out) { // if the first (or a single) character is a ZERO WIDTH NO-BREAK SPACE, write a BOM first // (this is because they are the same bytes and the first pair will be read as a BOM) if (ZERO_WIDTH_NO_BREAK_SPACE == c) out.writeChar(BYTE_ORDER_MARKER); out.writeChar(c); } - public void writeLengthAndChar(char c, WriteBuffer out) { + public void writeWchar_1_2(char c, WriteBuffer out) { // Older versions of Yoko ignore the encoded length and just read two bytes anyway. // So, never write a BOM, and stick to two bytes. out.writeByte(2); @@ -98,19 +98,19 @@ public void writeLengthAndChar(char c, WriteBuffer out) { COLLOCATED { public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.COLLOCATED; } - public int octetCount(String s) { return 2 * s.length(); } + public int octetCountWstring_1_2(String s) { return 2 * s.length(); } - public int octetCountLengthsAndWchars(int numChars) { return 2 * numChars; } + public int octetCountWchars_1_2(int numChars) { return 2 * numChars; } - public char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes) { return in.readChar(); } + public char readWchar_1_0(ReadBuffer in, boolean swapBytes) { return in.readChar(); } - public char readLengthAndChar(ReadBuffer in) { return in.readChar(); } + public char readWchar_1_2(ReadBuffer in) { return in.readChar(); } - public CharReader beginToReadString(ReadBuffer in) { return this::readChar; } + public WcharReader beginToReadWstring_1_2(ReadBuffer in) { return ReadBuffer::readChar; } - public void beginToWriteString(char c, WriteBuffer out) { out.writeChar(c); } + public void beginToWriteWstring_1_2(char c, WriteBuffer out) { out.writeChar(c); } - public void writeLengthAndChar(char c, WriteBuffer out) { out.writeChar(c);} + public void writeWchar_1_2(char c, WriteBuffer out) { out.writeChar(c);} }, /** * This codec is for use when no encoding is permitted. @@ -125,43 +125,46 @@ public void writeLengthAndChar(char c, WriteBuffer out) { @Override public int charSize() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } - @Override - public char readChar(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } - @Override public int octetCount(char c) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public int octetCount(String s) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public int octetCountWstring_1_2(String s) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public int octetCountLengthsAndWchars(int numChars) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public int octetCountWchars_1_2(int numChars) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public void writeChar(char c, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public char readWchar_1_0(ReadBuffer in, boolean swapBytes) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public void assertNoBufferedCharData() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public char readWchar_1_2(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public boolean readFinished() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public void writeWchar_1_0(char c, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public boolean writeFinished() { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public void writeWchar_1_2(char c, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public WcharReader beginToReadWstring_1_2(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } @Override - public char readLengthAndChar(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + public void beginToWriteWstring_1_2(char firstChar, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + }; - @Override - public void writeLengthAndChar(char c, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + @Override + public int charSize() { return 2; } - @Override - public CharReader beginToReadString(ReadBuffer in) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } + @Override + public int octetCount(char c) { return charSize(); } - @Override - public void beginToWriteString(char firstChar, WriteBuffer out) { throw new UnsupportedOperationException("attempt to use unspecified codec"); } - }; + @Override + public char readChar(ReadBuffer in) { return readWchar_1_0(in, false); } // only used for test + + @Override + public void writeChar(char c, WriteBuffer out) { writeWchar_1_0(c, out); } // only used for test + + @Override + public SimpleWcharCodec duplicate() { return this; } } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java index a3b28c95a..5135b9a61 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java @@ -211,14 +211,11 @@ private static int getUtf8Len(int codepoint) { public boolean writeFinished() { return 0 == highSurrogate; } @Override - public CharCodec getInstanceOrCopy() { return new Utf8Codec(); } + public CharCodec duplicate() { return new Utf8Codec(); } @Override public String name() { return "UTF-8"; } - @Override - public boolean isStateless() { return false; } - @Override public CodeSetInfo getCodeSetInfo() { return CodeSetInfo.UTF_8; } diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java index 8401a5e2c..356403623 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Util.java @@ -53,10 +53,9 @@ enum Util { static char require8bit(char c) { return c < (1<<8) ? c : ASCII_REPLACEMENT_CHAR; } /** Find a codec by name that encodes the Unicode codepoint for a char directly */ - static CharCodec getUnicodeCodec(String name) { + static CharCodec getUnicodeCharCodec(String name) { switch (name.toUpperCase()) { case "UTF-8": return new Utf8Codec(); - case "UTF-16": return SimpleWcharCodec.UTF_16; case "US-ASCII": return SimpleCharCodec.US_ASCII; case "ISO-8859-1": return SimpleCharCodec.ISO_LATIN_1; default: return null; diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java index 6041e5602..d7f4caa1e 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/WcharCodec.java @@ -20,55 +20,23 @@ import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; +import org.apache.yoko.orb.OB.CodeSetInfo; -import java.nio.charset.UnsupportedCharsetException; -import java.util.Optional; +public interface WcharCodec { + @FunctionalInterface interface WcharReader { char readWchar(ReadBuffer in); } -public interface WcharCodec extends CharCodec { - static WcharCodec getCollocatedWcharCodec() { return SimpleWcharCodec.COLLOCATED; } - static WcharCodec getDefaultWcharCodec() { return SimpleWcharCodec.UTF_16; } - static WcharCodec getUnspecifiedWcharCodec() { return SimpleWcharCodec.UNSPECIFIED; } + CodeSetInfo getCodeSetInfo(); - static WcharCodec forName(String name) { - return Optional.of(name) - .map(CharCodec::forName) - .filter(WcharCodec.class::isInstance) - .map(WcharCodec.class::cast) - .orElseThrow(() -> new UnsupportedCharsetException(name + " not supported for wchar")); - } + int octetCountWstring_1_2(String s); - static WcharCodec forRegistryId(int id) { - return Optional.of(id) - .map(CharCodec::forRegistryId) - .filter(WcharCodec.class::isInstance) - .map(WcharCodec.class::cast) - .orElseThrow(() -> new UnsupportedCharsetException("Charset with registry id " + id + " not supported for wchar")); - } - - @Override - default int charSize() { return 2; } - - @Override - default char readChar(ReadBuffer in) { return in.readChar(); } // UTF-16 chars are already in Java format - - @Override - default int octetCount(char c) { return 2; } - - int octetCount(String s); - - int octetCountLengthsAndWchars(int numChars); - - @Override - default void writeChar(char c, WriteBuffer out) { out.writeChar(c); } // Java chars are already in UTF-16 format + int octetCountWchars_1_2(int numChars); /** * In GIOP 1.0 and GIOP 1.1, wchars are encoded as EXACTLY 2 bytes, * aligned on a 2-byte boundary, and in the message/encapsulation byte ordering. * The alignment must be ensured by the caller. */ - char readCharWithEndianFlag(ReadBuffer in, boolean swapBytes); - - // We only ever write big-endian, so no writeWithEndianFlag() method is needed + char readWchar_1_0(ReadBuffer in, boolean swapBytes); /** * In GIOP 1.2, the wchar encoding requires a length byte before each wchar. @@ -76,14 +44,19 @@ static WcharCodec forRegistryId(int id) { * However, it can be 4, if the wchar is preceded by a BOM. * This method should be used to read a BOM and then a wchar, i.e. if the length byte was 4. */ - char readLengthAndChar(ReadBuffer in); + char readWchar_1_2(ReadBuffer in); + + /** + * Since we only ever write big-endian, no endianness parameter is required. + */ + default void writeWchar_1_0(char c, WriteBuffer out) { out.writeChar(c); } /** * In GIOP 1.2, wchars are preceded by a single octet. * This contains the number of octets in the char is encoding, * including any necessary BOM. */ - void writeLengthAndChar(char c, WriteBuffer out); + void writeWchar_1_2(char c, WriteBuffer out); /** * In GIOP 1.2, for UTF-16, there may be a byte-order marker to indicate the endianness of the encoded bytes. @@ -92,14 +65,14 @@ static WcharCodec forRegistryId(int id) { * * @return the endian-informed reader with which to read in the rest of the string. */ - CharReader beginToReadString(ReadBuffer in); + WcharReader beginToReadWstring_1_2(ReadBuffer in); /** * Under certain circumstances, it may be necessary to write a BOM at the start of a string. * To support this, this method will be called to write the first character of a wstring. */ - void beginToWriteString(char firstChar, WriteBuffer out); + void beginToWriteWstring_1_2(char firstChar, WriteBuffer out); /** Provides an identical object that can be used concurrently with this one */ - default WcharCodec getInstanceOrCopy() { return this; } + default WcharCodec duplicate() { return this; } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java index 9303f8ebe..526e00e0b 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoInputStream.java @@ -18,7 +18,7 @@ package org.apache.yoko.orb.CORBA; import org.apache.yoko.codecs.CharCodec; -import org.apache.yoko.codecs.CharCodec.CharReader; +import org.apache.yoko.codecs.WcharCodec.WcharReader; import org.apache.yoko.codecs.WcharCodec; import org.apache.yoko.io.AlignmentBoundary; import org.apache.yoko.io.Buffer; @@ -704,9 +704,9 @@ public char read_wchar() { case GIOP1_0: case GIOP1_1: readBuffer.align(TWO_BYTE_BOUNDARY); - return codecs.wcharCodec.readCharWithEndianFlag(readBuffer, swapBytes); + return codecs.wcharCodec.readWchar_1_0(readBuffer, swapBytes); default: - return codecs.wcharCodec.readLengthAndChar(readBuffer); + return codecs.wcharCodec.readWchar_1_2(readBuffer); } } catch (IndexOutOfBoundsException e) { throw newMarshalError(MinorReadWCharOverflow, e); @@ -824,7 +824,7 @@ public String read_string() { // as long as this is written explicitly in write_string() as well as here. // (i.e. do NOT use the codec to write the null terminator) if (readBuffer.readByte() != 0) throw newMarshalError(MinorReadStringNoTerminator); - + DATA_IN_LOG.fine(() -> String.format("Read string \"%s\", using %s codec end pos=0x%x", sb, codec, readBuffer.getPosition())); return sb.toString(); } @@ -865,10 +865,12 @@ private String read_wstring_pre_1_2() { char[] tmp = new char[numChars]; try { - for (int i = 0; i < numChars; i++) tmp[i] = codec.readCharWithEndianFlag(readBuffer, swapBytes); + for (int i = 0; i < numChars; i++) tmp[i] = codec.readWchar_1_0(readBuffer, swapBytes); // Check for terminating null wchar if (0 != tmp[numChars - 1]) throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadWStringNoTerminator); - return new String(tmp, 0, numChars - 1); + String result = new String(tmp, 0, numChars - 1); + DATA_IN_LOG.fine(() -> String.format("Read GIOP 1.0 wstring \"%s\", using %s codec end pos=0x%x", result, codec, readBuffer.getPosition())); + return result; } catch (IndexOutOfBoundsException e) { throw stringMarshallingError("GIOP 1.0 wstring", numChars, MinorReadWStringOverflow, e); } @@ -884,14 +886,15 @@ private String read_wstring_1_2() { DATA_IN_LOG.fine(() -> String.format("Reading GIOP 1.2 wstring of length %d octets using codec %s", numOctets, codec)); // In GIOP 1.2 there is no terminating null char, but there might be a BOM - StringBuilder builder = new StringBuilder(numOctets / 2); + StringBuilder sb = new StringBuilder(numOctets / 2); final int endPosition = readBuffer.getPosition() + numOctets; // this method checks for and consumes a BOM if present, returning the appropriately endian char reader - CharReader reader = codecs.wcharCodec.beginToReadString(readBuffer); + WcharReader reader = codecs.wcharCodec.beginToReadWstring_1_2(readBuffer); try { - while (readBuffer.getPosition() < endPosition) builder.append(reader.readChar(readBuffer)); - return builder.toString(); + while (readBuffer.getPosition() < endPosition) sb.append(reader.readWchar(readBuffer)); + DATA_IN_LOG.fine(() -> String.format("Read GIOP 1.2 wstring \"%s\", using %s codec end pos=0x%x", sb, codec, readBuffer.getPosition())); + return sb.toString(); } catch (IndexOutOfBoundsException e) { throw stringMarshallingError("GIOP 1.2 wstring", numOctets, MinorReadWStringOverflow, e); } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java index 663baffc2..637d09263 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/CORBA/YokoOutputStream.java @@ -447,15 +447,15 @@ public void write_wchar(char value) { case GIOP1_0: case GIOP1_1: // add aligned space for 1 character - addCapacity(codec.charSize(), TWO_BYTE_BOUNDARY); + addCapacity(2, TWO_BYTE_BOUNDARY); // write 2-byte character in big endian - codec.writeChar(value, writeBuffer); + codec.writeWchar_1_0(value, writeBuffer); break; default: // add unaligned space for 1 length-and-character - addCapacity(codec.octetCountLengthsAndWchars(1)); - codec.writeLengthAndChar(value, writeBuffer); + addCapacity(codec.octetCountWchars_1_2(1)); + codec.writeWchar_1_2(value, writeBuffer); break; } } @@ -545,9 +545,9 @@ private void write_wstring_pre_1_2(String value) { // already 4-byte aligned, so just add the needed capacity for len 2-byte chars addCapacity(2*(value.length() + 1)); // now write all the characters - for (int i = 0; i < value.length(); i++) codec.writeChar(value.charAt(i), writeBuffer); + for (int i = 0; i < value.length(); i++) codec.writeWchar_1_0(value.charAt(i), writeBuffer); // and the null terminator - codec.writeChar((char) 0, writeBuffer); + codec.writeWchar_1_0((char) 0, writeBuffer); } private void write_wstring_1_2(String value) { @@ -560,16 +560,16 @@ private void write_wstring_1_2(String value) { } // now we know there is a first character final WcharCodec codec = codecs.wcharCodec; - int numOctets = codec.octetCount(value); + int numOctets = codec.octetCountWstring_1_2(value); DATA_OUT_LOG.finest(() -> String.format("Codec %s will use %d octets to write a GIOP 1.2 wstring: \"%s\"", codec, numOctets, value)); // write the length of the string in octets write_ulong(numOctets); // add unaligned capacity addCapacity(numOctets); // write the first character, including optional BOM - codec.beginToWriteString(value.charAt(0), writeBuffer); + codec.beginToWriteWstring_1_2(value.charAt(0), writeBuffer); // write the rest of the characters - for (int i = 1; i < value.length(); i++) codec.writeChar(value.charAt(i), writeBuffer); + for (int i = 1; i < value.length(); i++) codec.writeWchar_1_0(value.charAt(i), writeBuffer); } public void write_boolean_array(boolean[] value, int offset, int length) { diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java index 567a5a326..924e6819d 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/CodecPair.java @@ -18,23 +18,25 @@ package org.apache.yoko.orb.OB; import org.apache.yoko.codecs.CharCodec; +import org.apache.yoko.codecs.Codex; import org.apache.yoko.codecs.WcharCodec; +import org.apache.yoko.orb.OCI.GiopVersion; import java.util.Objects; -import static org.apache.yoko.codecs.CharCodec.getCollocatedCharCodec; -import static org.apache.yoko.codecs.CharCodec.getDefaultCharCodec; -import static org.apache.yoko.codecs.CharCodec.getUnspecifiedCharCodec; -import static org.apache.yoko.codecs.WcharCodec.getCollocatedWcharCodec; -import static org.apache.yoko.codecs.WcharCodec.getDefaultWcharCodec; +import static org.apache.yoko.codecs.Codex.getCharCodec; +import static org.apache.yoko.codecs.Codex.getCollocatedCharCodec; +import static org.apache.yoko.codecs.Codex.getDefaultCharCodec; +import static org.apache.yoko.codecs.Codex.getCollocatedWcharCodec; +import static org.apache.yoko.codecs.Codex.getDefaultWcharCodec; +import static org.apache.yoko.codecs.Codex.getUnspecifiedWcharCodec; +import static org.apache.yoko.codecs.Codex.getWcharCodec; // This class may look immutable, but charCodec can contain state (while reading/writing a surrogate pair from/to UTF-8) public final class CodecPair { - /** - * The default codecs for GIOP 1.0. - * TODO: consider whether we need an UNSUPPORTED wchar codec that throws exceptions for wchars - */ - private static final CodecPair DEFAULT = new CodecPair(getDefaultCharCodec(), getDefaultWcharCodec()); + private static final CodecPair GIOP_1_0_DEFAULT = new CodecPair(getDefaultCharCodec(), getDefaultWcharCodec()); + private static final CodecPair GIOP_1_2_DEFAULT = new CodecPair(getCharCodec("UTF-8"), getDefaultWcharCodec()); + /** * Codecs to use for collocated invocations */ @@ -52,14 +54,6 @@ private CodecPair(CharCodec cc, WcharCodec wc) { this.wcharCodec = wc; } - private CodecPair(CodecPair that) { - this(that.charCodec.getInstanceOrCopy(), that.wcharCodec.getInstanceOrCopy()); - } - - private boolean isStateless() { - return charCodec.isStateless() && wcharCodec.isStateless(); - } - @Override public boolean equals(Object o) { if (!(o instanceof CodecPair)) return false; @@ -77,17 +71,28 @@ public String toString() { } public static CodecPair createCopy(CodecPair template) { - if (template == null) return createCopy(DEFAULT); - return template.isStateless() ? template : new CodecPair(template); + if (template == null) return createCopy(GIOP_1_0_DEFAULT); + CharCodec cc = template.charCodec.duplicate(); + WcharCodec wc = template.wcharCodec.duplicate(); + // if the codec instances are IDENTICAL then the template is stateless + boolean templateIsStateless = template.charCodec == cc && template.wcharCodec == wc; + return templateIsStateless ? template : new CodecPair(cc, wc); } public static CodecPair create(int tcs, int twcs) { - CharCodec cc = CharCodec.forRegistryId(tcs); - WcharCodec wc = WcharCodec.forRegistryId(twcs); + CharCodec cc = getCharCodec(tcs); + WcharCodec wc = getWcharCodec(twcs); return new CodecPair(cc, wc); } - public static CodecPair createForWcharWriteOnly() { - return new CodecPair(getUnspecifiedCharCodec(), getDefaultWcharCodec()); + public static CodecPair getDefaultCodecs(GiopVersion version) { + switch (version) { + case GIOP1_0: + return createCopy(GIOP_1_0_DEFAULT); + case GIOP1_1: + case GIOP1_2: + default: + return createCopy(GIOP_1_2_DEFAULT); + } } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java index 1077e9f83..4eae98cf6 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java @@ -278,7 +278,7 @@ public void setSystemException(SystemException ex) { private static void createUnknownExceptionServiceContexts(UnknownException ex, ServiceContexts replyContexts) { final Throwable t = ex.originalEx; try (CmsfOverride o = CmsfThreadLocal.override()) { - CodecPair codecs = CodecPair.createForWcharWriteOnly(); + CodecPair codecs = CodecPair.getDefaultCodecs(GIOP1_2); try (YokoOutputStream os = new YokoOutputStream(codecs, GIOP1_2)) { os._OB_writeEndian(); os.write_value(t, Throwable.class); diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java index e335a2d2e..1cd76096d 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractLatinCodecTest.java @@ -50,7 +50,7 @@ abstract class AbstractLatinCodecTest { final ReadBuffer readBuffer = writeBuffer.readFromStart(); AbstractLatinCodecTest(String name) { - this.codec = CharCodec.forName(name); + this.codec = Codex.getCharCodec(name); this.charset = Charset.forName(name); expectedChars = Charset.forName(name).decode(inputBytes).asReadOnlyBuffer(); expectedBytes = Charset.forName(name).encode(expectedChars); diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java index 6c8297730..ea1146ba0 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/AbstractSimpleCodecTest.java @@ -39,8 +39,8 @@ public abstract class AbstractSimpleCodecTest { final ExpectedCharWriter expectedCharWriter; final ExpectedCharReader expectedCharReader; - AbstractSimpleCodecTest(String name, ExpectedCharWriter expectedCharWriter, ExpectedCharReader expectedCharReader) { - this.codec = (CODEC)CharCodec.forName(name); + AbstractSimpleCodecTest(CODEC codec, ExpectedCharWriter expectedCharWriter, ExpectedCharReader expectedCharReader) { + this.codec = codec; this.expectedCharWriter = expectedCharWriter; this.expectedCharReader = expectedCharReader; } @@ -79,7 +79,7 @@ void assertEncoding(char c, char expected) { // For WcharCodecs, check beginToWriteString() too if (!(codec instanceof WcharCodec)) return; newWriteBuffer(); - ((WcharCodec)codec).beginToWriteString(c, out); + ((WcharCodec)codec).beginToWriteWstring_1_2(c, out); in = getReadBuffer(); assertEquals(expected, expectedCharReader.readFrom(in)); } diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java index d2827347e..a2bda855c 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/IsoLatin1Test.java @@ -22,10 +22,11 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import static org.apache.yoko.codecs.SimpleCharCodec.ISO_LATIN_1; import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_CHAR; class IsoLatin1Test extends AbstractSimpleCodecTest implements TestData { - IsoLatin1Test() { super("ISO-8859-1", WriteBuffer::writeByte, ReadBuffer::readByteAsChar); } + IsoLatin1Test() { super(ISO_LATIN_1, WriteBuffer::writeByte, ReadBuffer::readByteAsChar); } boolean isDoubleByte() { return false; } @ParameterizedTest(name = "ISO-8859-1 decode/encode ASCII char: {0} ({2})") diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java index 8b3e90efc..34ca20cf7 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/UsAsciiTest.java @@ -25,7 +25,7 @@ import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_CHAR; class UsAsciiTest extends AbstractSimpleCodecTest implements TestData { - UsAsciiTest() { super("US-ASCII", WriteBuffer::writeByte, ReadBuffer::readByteAsChar); } + UsAsciiTest() { super(SimpleCharCodec.US_ASCII, WriteBuffer::writeByte, ReadBuffer::readByteAsChar); } boolean isDoubleByte() { return false; } @ParameterizedTest(name = "US-ASCII decode/encode ASCII char: {0} ({2})") diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java index cd0ef3a11..5f41827f2 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf16Test.java @@ -20,7 +20,7 @@ import org.apache.yoko.io.Buffer; import org.apache.yoko.io.ReadBuffer; import org.apache.yoko.io.WriteBuffer; -import org.apache.yoko.codecs.CharCodec.CharReader; +import org.apache.yoko.codecs.WcharCodec.WcharReader; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -31,14 +31,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -class Utf16Test extends AbstractSimpleCodecTest implements TestData { +class Utf16Test extends AbstractSimpleCodecTest implements TestData { static final char BOM = '\uFEFF'; static final char ANTI_BOM = '\uFFFE'; private static final ExpectedCharReader READ_CHAR = ReadBuffer::readChar; private static final ExpectedCharWriter WRITE_CHAR = WriteBuffer::writeChar; - Utf16Test() { super("UTF-16", WriteBuffer::writeChar, ReadBuffer::readChar); } + Utf16Test() { super(SimpleWcharCodec.UTF_16, WriteBuffer::writeChar, ReadBuffer::readChar); } boolean isDoubleByte() { return true; } @@ -114,12 +114,12 @@ void testBomBomLittleEndian() { private void assertEndianCharIs(char expectedChar) { ReadBuffer bomA = getReadBuffer(); - assertEquals(expectedChar, codec.readLengthAndChar(bomA)); + assertEquals(expectedChar, codec.readWchar_1_2(bomA)); codec.assertNoBufferedCharData(); assertTrue(bomA.isComplete()); // now skip back 4 bytes and try to read it as the first char of a string bomA.skipBytes(-4); - assertEquals(expectedChar, codec.beginToReadString(bomA).readChar(bomA)); + assertEquals(expectedChar, codec.beginToReadWstring_1_2(bomA).readWchar(bomA)); codec.assertNoBufferedCharData(); assertTrue(bomA.isComplete()); } @@ -132,7 +132,7 @@ void testBomOnItsOwn() { // then either this was an empty string, or if we are expecting a char // it genuinely is a single ZERO WIDTH NO BREAK SPACE character (also 0xFEFF) ReadBuffer singleBom = getReadBuffer(); - assertEquals(BOM, codec.readLengthAndChar(singleBom)); + assertEquals(BOM, codec.readWchar_1_2(singleBom)); assertTrue(singleBom.isComplete()); } @@ -141,7 +141,7 @@ void testBomOnItsOwnLittleEndian() { writeExpectedChar(ANTI_BOM); // If the only character available is a byte-swapped BOM (0xFFFE), // then either this was an empty string, or if we are expecting a char - // it genuinely is a single reserved unicode character (also 0xFFFE) + // it genuinely is a single reserved Unicode character (also 0xFFFE) ReadBuffer singleBom = getReadBuffer(); assertEquals(ANTI_BOM, codec.readChar(singleBom)); assertTrue(singleBom.isComplete()); @@ -170,10 +170,10 @@ void testStringOfCharsLittleEndian(String expected) { private void testStringOfChars(String expected, boolean swap) { for (char c: expected.toCharArray()) writeExpectedChar(c); ReadBuffer in = swap ? getByteSwappedReadBuffer() : getReadBuffer(); - CharReader rdr = codec.beginToReadString(in); + WcharReader rdr = codec.beginToReadWstring_1_2(in); StringBuilder sb = new StringBuilder(); while (!in.isComplete()) { - sb.append(rdr.readChar(in)); + sb.append(rdr.readWchar(in)); } assertEquals(expected, sb.toString()); } diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java index 6ff9cb671..216000201 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8InvalidTest.java @@ -33,7 +33,7 @@ class Utf8InvalidTest implements TestData { static final int MIN_1_BYTE = 0, MIN_2_BYTE = 1<<7, MIN_3_BYTE = 1 << 5+6, MIN_4_BYTE = 1 << 4+6+6; - final CharCodec codec = CharCodec.forName("UTF-8"); + final CharCodec codec = Codex.getCharCodec("UTF-8"); final WriteBuffer out = Buffer.createWriteBuffer(4); ReadBuffer in; diff --git a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java index 3c83f45df..fd1d2ab63 100644 --- a/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java +++ b/yoko-core/src/test/java/org/apache/yoko/codecs/Utf8Test.java @@ -40,7 +40,7 @@ class Utf8Test implements TestData { static final int MIN_1_BYTE = 0, MIN_2_BYTE = 1<<7, MIN_3_BYTE = 1 << 5+6, MIN_4_BYTE = 1 << 4+6+6; static final Charset UTF_8 = Charset.forName("UTF-8"); - final CharCodec codec = CharCodec.forName("UTF-8"); + final CharCodec codec = Codex.getCharCodec("UTF-8"); final WriteBuffer out = Buffer.createWriteBuffer(4); static Stream _1_ByteChars() { return testRange(MIN_1_BYTE, MIN_2_BYTE).mapToObj(TestData::toHexIntAndString); } From 5de0abf32c34853266238e25132a469e665e51de Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Sat, 7 Feb 2026 21:55:28 +0000 Subject: [PATCH 11/18] refactor: tidy POA_impl and ServantDispatcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve code readability and maintainability in POA implementation and servant dispatcher through consistent formatting and simplification. Changes in POA_impl.java: - Add static imports for commonly used constants and methods: - ObjectKey.ParseObjectKey, SynchronizationPolicyValue constants - MinorCodes constants and description methods - Convert logging statements to use lambda expressions for lazy evaluation - find_POA(), create_POA() now use lambda logging - Simplify conditional statements and remove unnecessary braces: - Inline single-statement if blocks where appropriate - Remove redundant null checks before throws - Remove excessive blank lines and comment blocks: - Remove "// ----" separator lines - Remove empty comment blocks with just "//" - Consolidate multi-line comments to single lines where appropriate - Improve method formatting: - Align method parameters consistently - Remove unnecessary line breaks in method signatures - Simplify stream operations: - Replace .stream().toArray() with .toArray(new Type[0]) - Add early break in loop when condition is met - Remove unused imports: - Remove java.util.Enumeration (replaced with Collection.forEach) - Remove org.apache.yoko.util.MinorCodes (now using static imports) - Replace Enumeration iteration with modern forEach: - _OB_etherealize() now uses children_.values().forEach() - Fix typos in comments: - "Eterealize" → "Etherealize" - "assocatied" → "associated" - "might operation" → "might operate" - Improve error message formatting: - Use static imports for MinorCodes description methods - Consolidate multi-line exception constructions Changes in ServantDispatcher.java: - Rename fields for clarity: - upcall_ → upcall - servant_ → servant - Add missing imports for better IDE support - Simplify dispatchBase() method: - Replace binary search with switch statement on operation name - Remove unnecessary intermediate variables - Make operation name matching more explicit - Make Abort exception static (no need for outer class reference) - Improve variable naming: - _ob_op → opName - Remove Hungarian notation prefixes - Consolidate variable declarations with usage - Remove excessive blank lines and comments - Simplify conditional logic: - Remove unnecessary braces for single-statement blocks - Inline simple conditions Changes in GIOPConnection.java: - Fix grammar: "decision making" → "decision-making" Rationale: This refactoring improves code maintainability without changing behavior: - Lambda logging prevents string formatting when logging is disabled - Static imports reduce verbosity for frequently used constants - Modern Java idioms (forEach, enhanced switch) improve readability - Consistent formatting makes code easier to scan and understand - Removing excessive comments and blank lines reduces visual clutter - Better variable names make code self-documenting No functional changes - purely formatting and style improvements. --- .../apache/yoko/orb/OB/GIOPConnection.java | 2 +- .../yoko/orb/OBPortableServer/POA_impl.java | 427 +++++------------- .../OBPortableServer/ServantDispatcher.java | 191 ++++---- 3 files changed, 180 insertions(+), 440 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java index 2db9e94be..a2a4ca3aa 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/GIOPConnection.java @@ -312,7 +312,7 @@ private synchronized Upcall processRequest(GIOPIncomingMessage msg) { YokoInputStream in = msg.input(); - // We have some decision making to do here if BiDir is + // We have some decision-making to do here if BiDir is // enabled: // - If this is a client then make sure to properly // evaluate the message and obtain the correct OAInterface diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java index 0214676d3..7ff36f25a 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java @@ -57,7 +57,6 @@ import org.apache.yoko.orb.PortableServer.ServantRetentionPolicy_impl; import org.apache.yoko.orb.PortableServer.ThreadPolicy_impl; import org.apache.yoko.util.Assert; -import org.apache.yoko.util.MinorCodes; import org.omg.BiDirPolicy.BOTH; import org.omg.CORBA.BAD_INV_ORDER; import org.omg.CORBA.BAD_PARAM; @@ -124,7 +123,6 @@ import org.omg.PortableServer.ThreadPolicy; import org.omg.PortableServer.ThreadPolicyValue; -import java.util.Enumeration; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -135,8 +133,16 @@ import static java.util.Arrays.stream; import static java.util.stream.Stream.concat; +import static org.apache.yoko.orb.OB.ObjectKey.ParseObjectKey; +import static org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyValue._NO_SYNCHRONIZATION; +import static org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyValue._SYNCHRONIZE_ON_ORB; +import static org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyValue._SYNCHRONIZE_ON_POA; +import static org.apache.yoko.util.MinorCodes.MinorCannotDispatch; +import static org.apache.yoko.util.MinorCodes.MinorInvalidObjectId; import static org.apache.yoko.util.MinorCodes.MinorSystemExceptionInUnknownAdapter; +import static org.apache.yoko.util.MinorCodes.describeBadParam; import static org.apache.yoko.util.MinorCodes.describeObjAdapter; +import static org.apache.yoko.util.MinorCodes.describeObjectNotExist; import static org.omg.CORBA.CompletionStatus.COMPLETED_NO; import static org.omg.PortableServer.IdAssignmentPolicyValue.SYSTEM_ID; import static org.omg.PortableServer.IdUniquenessPolicyValue.MULTIPLE_ID; @@ -216,9 +222,7 @@ private boolean validatePolicies(POAPolicies policies, Policy[] policyList, IntH if (USE_DEFAULT_SERVANT == policies.requestProcessingPolicy() && MULTIPLE_ID != policies.idUniquenessPolicy()) { // Since USE_DEFAULT_SERVANT, this must be present - boolean ok = findPolicyIndex(policyList, - REQUEST_PROCESSING_POLICY_ID.value, - i); + boolean ok = findPolicyIndex(policyList, REQUEST_PROCESSING_POLICY_ID.value, i); Assert.ensure(ok); return false; } @@ -264,8 +268,8 @@ private void completeDestroy() { manager_ = null; } if (callAdapterStateChange_) { - ObjectReferenceTemplate[] orts = childTemplates_.stream().toArray(ObjectReferenceTemplate[]::new); - orbInstance_.getPIManager().adapterStateChange(orts, NON_EXISTENT.value); + ObjectReferenceTemplate[] arr = childTemplates_.toArray(new ObjectReferenceTemplate[0]); + orbInstance_.getPIManager().adapterStateChange(arr, NON_EXISTENT.value); } servantLocationStrategy_.destroy(this, poaControl_.etherealize()); adapterActivator_.destroy(); @@ -297,7 +301,7 @@ private POA_impl(org.omg.CORBA.ORB orb, ociCurrent_ = ociCurrent; rawPolicies_ = rawPolicies; - logger.fine("Creating POA " + name + " using manager " + manager.get_id()); + logger.fine(() -> "Creating POA " + name + " using manager " + manager.get_id()); poaId_ = null == parent ? new String[0] : concat(stream(parent.poaId_), Stream.of(name)).toArray(String[]::new); poaCreateTime_ = (int) (System.currentTimeMillis() / 1000); @@ -377,7 +381,6 @@ private static Policy[] getDefaultRawPolicies() { @SuppressWarnings("deprecation") protected void finalize() throws Throwable { Assert.ensure(poaControl_.getDestroyed()); - super.finalize(); } @@ -392,23 +395,18 @@ public org.omg.PortableServer.POA create_POA(String adapter, InvalidPolicy { Assert.ensure(adapter != null); - // // Has the POA been destroyed? - // if (poaControl_.getDestroyed()) { throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); } logger.fine("POA " + name_ + " creating new POA with name " + adapter); - // // Are the requested policies valid? - // POAPolicies policies = new POAPolicies(orbInstance_, rawPolicies); IntHolder idx = new IntHolder(); if (!validatePolicies(policies, rawPolicies, idx)) - throw new InvalidPolicy( - (short) idx.value); + throw new InvalidPolicy((short) idx.value); POA_impl child; @@ -419,9 +417,7 @@ public org.omg.PortableServer.POA create_POA(String adapter, // (by calling create_POA again) // synchronized (children_) { - if (children_.containsKey(adapter)) { - throw new AdapterAlreadyExists(); - } + if (children_.containsKey(adapter)) throw new AdapterAlreadyExists(); // If necessary create a new POAManager for this POA POAManager obmanager; @@ -442,14 +438,12 @@ public org.omg.PortableServer.POA create_POA(String adapter, } } - // // Create the new POA - // try { child = new POA_impl(orb_, orbInstance_, serverId_, adapter, this, obmanager, poaCurrent_, ociCurrent_, policies, rawPolicies); } catch (SystemException ex) { // If the creation of the POA fails and a new POAManager - // was created the deactivate the POAManager + // was created then deactivate the POAManager if (manager == null) { Assert.ensure(obmanager != null); try { @@ -460,9 +454,7 @@ public org.omg.PortableServer.POA create_POA(String adapter, throw ex; } - // // Add this to the child list - // children_.put(adapter, child); } @@ -472,7 +464,7 @@ public org.omg.PortableServer.POA create_POA(String adapter, public org.omg.PortableServer.POA find_POA(String adapter, boolean activate) throws AdapterNonExistent { Objects.requireNonNull(adapter); if (poaControl_.getDestroyed()) throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); - logger.fine("POA " + name_ + " finding POA with name " + adapter); + logger.fine(() -> "POA " + name_ + " finding POA with name " + adapter); org.omg.PortableServer.POA poa = children_.get(adapter); if (null != poa) return poa; @@ -516,58 +508,42 @@ public void destroy(boolean etherealize, boolean waitForCompletion) { // Factories for policy objects // ---------------------------------------------------------------------- - // // These methods don't bother to check to see if the POA has // already been destroyed - // - public ThreadPolicy create_thread_policy( - ThreadPolicyValue value) { + public ThreadPolicy create_thread_policy(ThreadPolicyValue value) { return new ThreadPolicy_impl(value); } - public LifespanPolicy create_lifespan_policy( - LifespanPolicyValue value) { + public LifespanPolicy create_lifespan_policy(LifespanPolicyValue value) { return new LifespanPolicy_impl(value); } - public IdUniquenessPolicy create_id_uniqueness_policy( - IdUniquenessPolicyValue value) { - return new IdUniquenessPolicy_impl( - value); + public IdUniquenessPolicy create_id_uniqueness_policy(IdUniquenessPolicyValue value) { + return new IdUniquenessPolicy_impl(value); } - public IdAssignmentPolicy create_id_assignment_policy( - IdAssignmentPolicyValue value) { - return new IdAssignmentPolicy_impl( - value); + public IdAssignmentPolicy create_id_assignment_policy(IdAssignmentPolicyValue value) { + return new IdAssignmentPolicy_impl(value); } - public ImplicitActivationPolicy create_implicit_activation_policy( - ImplicitActivationPolicyValue value) { - return new ImplicitActivationPolicy_impl( - value); + public ImplicitActivationPolicy create_implicit_activation_policy(ImplicitActivationPolicyValue value) { + return new ImplicitActivationPolicy_impl(value); } - public ServantRetentionPolicy create_servant_retention_policy( - ServantRetentionPolicyValue value) { - return new ServantRetentionPolicy_impl( - value); + public ServantRetentionPolicy create_servant_retention_policy(ServantRetentionPolicyValue value) { + return new ServantRetentionPolicy_impl(value); } - public RequestProcessingPolicy create_request_processing_policy( - RequestProcessingPolicyValue value) { - return new RequestProcessingPolicy_impl( - value); + public RequestProcessingPolicy create_request_processing_policy(RequestProcessingPolicyValue value) { + return new RequestProcessingPolicy_impl(value); } - public SynchronizationPolicy create_synchronization_policy( - SynchronizationPolicyValue value) { + public SynchronizationPolicy create_synchronization_policy(SynchronizationPolicyValue value) { return new SynchronizationPolicy_impl(value); } - public DispatchStrategyPolicy create_dispatch_strategy_policy( - DispatchStrategy value) { + public DispatchStrategyPolicy create_dispatch_strategy_policy(DispatchStrategy value) { return new DispatchStrategyPolicy_impl(value); } @@ -647,8 +623,7 @@ public ObjectReferenceTemplate adapter_template() { public ObjectReferenceFactory current_factory() { if (iorInfo_ != null) { try { - return iorInfo_ - .current_factory(); + return iorInfo_.current_factory(); } catch (ClassCastException e) { return iorInfo_.current_factory(); } @@ -664,14 +639,12 @@ public org.omg.CORBA.ORB the_ORB() { // Servant manager registration // ---------------------------------------------------------------------- - public ServantManager get_servant_manager() - throws WrongPolicy { + public ServantManager get_servant_manager() throws WrongPolicy { if (poaControl_.getDestroyed()) { throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); } - ServantManagerStrategy servantManagerStrategy = servantLocationStrategy_ - .getServantManagerStrategy(); + ServantManagerStrategy servantManagerStrategy = servantLocationStrategy_.getServantManagerStrategy(); if (servantManagerStrategy == null) { throw new WrongPolicy(); @@ -760,42 +733,26 @@ public void activate_object_with_id(byte[] oid, Servant servant) throws ServantA Assert.ensure(servant != null); if (poaControl_.getDestroyed()) throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); - - - // // Validate that the ObjectId is valid - // if (!idGenerationStrategy_.isValid(oid)) - throw new BAD_PARAM( - MinorCodes - .describeBadParam(MinorCodes.MinorInvalidObjectId) - + ": POA has SYSTEM_ID policy but the object ID was not " - + "generated by this POA", - MinorCodes.MinorInvalidObjectId, - COMPLETED_NO); + throw new BAD_PARAM(describeBadParam(MinorInvalidObjectId) + + ": POA has SYSTEM_ID policy but the object ID was not generated by this POA", + MinorInvalidObjectId, COMPLETED_NO); servantLocationStrategy_.activate(oid, servant); - - // // Notify associated routers of activation - // notifyRouters(true, oid); } public void deactivate_object(byte[] oid) throws ObjectNotActive, WrongPolicy { if (poaControl_.getDestroyed()) throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); - servantLocationStrategy_.deactivate(this, oid); - - // // Notify associated routers of activation - // notifyRouters(false, oid); } - public org.omg.CORBA.Object create_reference(String intf) - throws WrongPolicy { + public org.omg.CORBA.Object create_reference(String intf) throws WrongPolicy { Assert.ensure(intf != null); if (poaControl_.getDestroyed()) { @@ -816,31 +773,23 @@ public org.omg.CORBA.Object create_reference_with_id(byte[] oid, String intf) { // Validate that the ObjectId is valid // if (!idGenerationStrategy_.isValid(oid)) - throw new BAD_PARAM( - MinorCodes - .describeBadParam(MinorCodes.MinorInvalidObjectId) - + ": POA has SYSTEM_ID policy but the object ID was not " - + "generated by this POA", - MinorCodes.MinorInvalidObjectId, - COMPLETED_NO); + throw new BAD_PARAM(describeBadParam(MinorInvalidObjectId) + + ": POA has SYSTEM_ID policy but the object ID was not generated by this POA", + MinorInvalidObjectId, COMPLETED_NO); return ort().make_object(intf, oid); } - public byte[] servant_to_id(Servant servant) - throws ServantNotActive, - WrongPolicy { + public byte[] servant_to_id(Servant servant) throws ServantNotActive, WrongPolicy { Assert.ensure(servant != null); if (poaControl_.getDestroyed()) { throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); } - // // Requires USE_DEFAULT_SERVANT policy or RETAIN policy and // either the UNIQUE_ID policy or the IMPLICIT_ACTIVATION (w/ // SYSTEM_ID) policies. - // if (policies_.requestProcessingPolicy() != USE_DEFAULT_SERVANT && (policies_.servantRetentionPolicy() != RETAIN || (policies_ .idUniquenessPolicy() != UNIQUE_ID && policies_ @@ -850,28 +799,22 @@ public byte[] servant_to_id(Servant servant) byte[] oid = servantLocationStrategy_.servantToId(servant, poaCurrent_); if (oid == null) { - // // If the POA doesn't have the IMPLICIT_ACTIVATION // (w/ SYSTEM_ID) then a ServantNotActive exception - // if (policies_.implicitActivationPolicy() != IMPLICIT_ACTIVATION) throw new ServantNotActive(); try { oid = activate_object(servant); } catch (ServantAlreadyActive ex) { - throw Assert.fail(ex); // Should - // not occur + throw Assert.fail(ex); // Should not occur } } return oid; } - public org.omg.CORBA.Object servant_to_reference( - Servant servant) - throws ServantNotActive, - WrongPolicy { + public org.omg.CORBA.Object servant_to_reference(Servant servant) throws ServantNotActive, WrongPolicy { Assert.ensure(servant != null); if (poaControl_.getDestroyed()) { @@ -883,8 +826,7 @@ public org.omg.CORBA.Object servant_to_reference( // request on the specified servant, the reference associated // with the current invocation is returned. // - if (poaCurrent_._OB_inUpcall() - && poaCurrent_._OB_getServant() == servant) { + if (poaCurrent_._OB_inUpcall() && poaCurrent_._OB_getServant() == servant) { try { byte[] oid = poaCurrent_.get_object_id(); assert servant != null; @@ -901,11 +843,7 @@ public org.omg.CORBA.Object servant_to_reference( return create_reference_with_id(oid, intf); } - public Servant reference_to_servant( - org.omg.CORBA.Object reference) - throws ObjectNotActive, - WrongAdapter, - WrongPolicy { + public Servant reference_to_servant(org.omg.CORBA.Object reference) throws ObjectNotActive, WrongAdapter, WrongPolicy { Assert.ensure(reference != null); if (poaControl_.getDestroyed()) { @@ -931,8 +869,7 @@ public Servant reference_to_servant( return servant; } - public byte[] reference_to_id(org.omg.CORBA.Object reference) - throws WrongAdapter { + public byte[] reference_to_id(org.omg.CORBA.Object reference) throws WrongAdapter { Assert.ensure(reference != null); if (poaControl_.getDestroyed()) { @@ -940,13 +877,10 @@ public byte[] reference_to_id(org.omg.CORBA.Object reference) } assert reference != null; - Delegate d = (Delegate) ((ObjectImpl) reference) - ._get_delegate(); + Delegate d = (Delegate) ((ObjectImpl) reference)._get_delegate(); IOR ior = d._OB_IOR(); - // // Extract the object key from the IOR of the object reference. - // POAManager_impl m = (POAManager_impl) manager_; Acceptor[] acceptors = m._OB_getAcceptors(); @@ -955,22 +889,18 @@ public byte[] reference_to_id(org.omg.CORBA.Object reference) for (int i = 0; i < acceptors.length && !local; i++) { profileInfos = acceptors[i].get_local_profiles(ior); - if (profileInfos.length > 0) + if (profileInfos.length > 0) { local = true; + break; + } } - // // Is the key local? - // if (local) { - // // Verify the poaIds are the same, have the persistency // values and the same create time if transient - // ObjectKeyData keyData = new ObjectKeyData(); - if (ObjectKey.ParseObjectKey( - profileInfos[0].key, keyData) - && _OB_poaMatches(keyData, true)) { + if (ParseObjectKey(profileInfos[0].key, keyData) && _OB_poaMatches(keyData, true)) { return keyData.oid; } } @@ -978,45 +908,33 @@ && _OB_poaMatches(keyData, true)) { throw new WrongAdapter(); } - public Servant id_to_servant(byte[] oid) - throws ObjectNotActive, - WrongPolicy { + public Servant id_to_servant(byte[] oid) throws ObjectNotActive, WrongPolicy { if (poaControl_.getDestroyed()) { throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); } - // // Requires the RETAIN policy or the USE_DEFAULT_SERVANT policy. - // if (policies_.servantRetentionPolicy() != RETAIN && policies_.requestProcessingPolicy() != USE_DEFAULT_SERVANT) throw new WrongPolicy(); - Servant servant = servantLocationStrategy_ - .idToServant(oid, true); + Servant servant = servantLocationStrategy_.idToServant(oid, true); - if (servant == null) - throw new ObjectNotActive(); + if (servant == null) throw new ObjectNotActive(); return servant; } - public org.omg.CORBA.Object id_to_reference(byte[] oid) - throws ObjectNotActive, - WrongPolicy { + public org.omg.CORBA.Object id_to_reference(byte[] oid) throws ObjectNotActive, WrongPolicy { if (poaControl_.getDestroyed()) { throw new OBJECT_NOT_EXIST("POA " + name_ + " has been destroyed"); } // Requires the RETAIN policy - // - if (policies_.servantRetentionPolicy() != RETAIN) - throw new WrongPolicy(); + if (policies_.servantRetentionPolicy() != RETAIN) throw new WrongPolicy(); - Servant servant = servantLocationStrategy_ - .idToServant(oid, false); - if (servant == null) - throw new ObjectNotActive(); + Servant servant = servantLocationStrategy_.idToServant(oid, false); + if (servant == null) throw new ObjectNotActive(); String intf = servant._all_interfaces(this, oid)[0]; return ort().make_object(intf, oid); @@ -1034,39 +952,25 @@ public byte[] id() { // Yoko specific functions // ---------------------------------------------------------------------- - public void _OB_preinvoke(String op, byte[] oid, - Servant servant, Object cookie, - TransportInfo info) { - // + public void _OB_preinvoke(String op, byte[] oid, Servant servant, Object cookie, TransportInfo info) { // preinvoke the servant location strategy - // servantLocationStrategy_.preinvoke(oid); - // // Setup the OCI::Current context - // ociCurrent_._OB_preinvoke(info); - // // Setup the PortableServer::Current context - // poaCurrent_._OB_preinvoke(this, servant, op, oid, cookie); - // - // Depending on the synchronization policy we have to lock a - // variety of mutexes. - // + // Depending on the synchronization policy we have to lock a variety of mutexes. // TODO: DUMP THIS IF POSSIBLE - // switch (policies_.synchronizationPolicy().value()) { - case SynchronizationPolicyValue._NO_SYNCHRONIZATION: + case _NO_SYNCHRONIZATION: break; - - case SynchronizationPolicyValue._SYNCHRONIZE_ON_POA: + case _SYNCHRONIZE_ON_POA: poaSyncMutex_.lock(); break; - - case SynchronizationPolicyValue._SYNCHRONIZE_ON_ORB: + case _SYNCHRONIZE_ON_ORB: orbInstance_.getORBSyncMutex().lock(); break; } @@ -1078,21 +982,17 @@ public void _OB_postinvoke() { Servant servant = poaCurrent_._OB_getServant(); Object cookie = poaCurrent_._OB_getCookie(); - // // Depending on the synchronization policy we have to unlock a // variety of mutexes. Note that we have to do this before - // calling postinvoke else we might operation on a destroyed + // calling postinvoke else we might operate on a destroyed // servant. - // switch (policies_.synchronizationPolicy().value()) { - case SynchronizationPolicyValue._NO_SYNCHRONIZATION: + case _NO_SYNCHRONIZATION: break; - - case SynchronizationPolicyValue._SYNCHRONIZE_ON_POA: + case _SYNCHRONIZE_ON_POA: poaSyncMutex_.unlock(); break; - - case SynchronizationPolicyValue._SYNCHRONIZE_ON_ORB: + case _SYNCHRONIZE_ON_ORB: orbInstance_.getORBSyncMutex().unlock(); break; } @@ -1113,42 +1013,26 @@ public void _OB_postinvoke() { servantLocationStrategy_.postinvoke(oid, this, op, cookie, servant); } - void _OB_locateServant(byte[] oid) - throws LocationForward { + void _OB_locateServant(byte[] oid) throws LocationForward { CookieHolder cookieHolder = new CookieHolder(); String op = "_locate"; - Servant servant = servantLocationStrategy_ - .locate(oid, this, op, cookieHolder); + Servant servant = servantLocationStrategy_.locate(oid, this, op, cookieHolder); if (servant == null) - throw new OBJECT_NOT_EXIST( - MinorCodes - .describeObjectNotExist(MinorCodes.MinorCannotDispatch), - MinorCodes.MinorCannotDispatch, - COMPLETED_NO); + throw new OBJECT_NOT_EXIST(describeObjectNotExist(MinorCannotDispatch), MinorCannotDispatch, COMPLETED_NO); servantLocationStrategy_.preinvoke(oid); - servantLocationStrategy_.postinvoke(oid, this, op, cookieHolder.value, - servant); + servantLocationStrategy_.postinvoke(oid, this, op, cookieHolder.value, servant); } - // // Create the upcall object for a method invocation - // - Upcall _OB_createUpcall(byte[] oid, - UpcallReturn upcallReturn, - ProfileInfo profileInfo, - TransportInfo transportInfo, int requestId, - String op, YokoInputStream in, - ServiceContexts requestContexts) throws LocationForward { + Upcall _OB_createUpcall(byte[] oid, UpcallReturn upcallReturn, ProfileInfo profileInfo, TransportInfo transportInfo, int requestId, String op, YokoInputStream in, ServiceContexts requestContexts) throws LocationForward { // Increment the outstanding request count if (!poaControl_.incrementRequestCount()) return null; final Upcall upcall; - // // Create the upcall object - // if (policies_.interceptorCallPolicy()) { PIManager piManager = orbInstance_.getPIManager(); @@ -1156,10 +1040,7 @@ Upcall _OB_createUpcall(byte[] oid, PIUpcall piUpcall = new PIUpcall(orbInstance_, upcallReturn, profileInfo, transportInfo, requestId, op, in, requestContexts, piManager); upcall = piUpcall; - // - // Call the receive_request_service_contexts - // interception point - // + // Call the receive_request_service_contexts interception point boolean failed = true; try { piUpcall.receiveRequestServiceContexts(rawPolicies_, adapterId_, oid, adapterTemplate_); @@ -1183,7 +1064,6 @@ Upcall _OB_createUpcall(byte[] oid, _OB_decrementRequestCount(); } - // // If this POA has a BidirPolicy set to BOTH and we have // received some listening points in the service context // (implying the client has the BidirPolicy as well), @@ -1191,64 +1071,42 @@ Upcall _OB_createUpcall(byte[] oid, // _OB_handleBidirContext(transportInfo, requestContexts); - return upcall; } - // // Dispatch a method invocation - // public void _OB_dispatch(byte[] oid, Upcall upcall) { String op = upcall.operation(); - // // Notify the PIUpcall about a potential change in thread // context. This has to be done before the servant is located // since PICurrent information has to be available in servant // locators. - // upcall.contextSwitch(); try { - // - // Locating a servant can throw LocationForward and - // SystemException errors - // + // Locating a servant can throw LocationForward and SystemException errors CookieHolder cookieHolder = new CookieHolder(); - Servant servant = servantLocationStrategy_ - .locate(oid, this, op, cookieHolder); + Servant servant = servantLocationStrategy_.locate(oid, this, op, cookieHolder); - // // If there is a servant then dispatch the request - // if (servant != null) { - TransportInfo transportInfo = upcall - .transportInfo(); + TransportInfo transportInfo = upcall.transportInfo(); - // // Do any pre invocation stuff - // - _OB_preinvoke(op, oid, servant, cookieHolder.value, - transportInfo); + _OB_preinvoke(op, oid, servant, cookieHolder.value, transportInfo); - // // The Upcall may call _OB_postinvoke - // upcall.setServantAndPOA(servant, this); - // // Dispatch the request - // try { - ServantDispatcher dispatcher = new ServantDispatcher( - upcall, servant); + ServantDispatcher dispatcher = new ServantDispatcher(upcall, servant); dispatcher.dispatch(); } finally { - // // If postinvoke() hasn't been called, then do it now, // since it may raise an exception that must be returned // to the client - // if (!upcall.postinvokeCalled()) { _OB_postinvoke(); // May raise SystemException } @@ -1261,46 +1119,27 @@ public void _OB_dispatch(byte[] oid, Upcall upcall) { out.write_boolean(true); upcall.postMarshal(); } else { - upcall - .setSystemException(new OBJECT_NOT_EXIST( - MinorCodes - .describeObjectNotExist(MinorCodes.MinorCannotDispatch), - MinorCodes.MinorCannotDispatch, - COMPLETED_NO)); + upcall.setSystemException(new OBJECT_NOT_EXIST(describeObjectNotExist(MinorCannotDispatch), MinorCannotDispatch, COMPLETED_NO)); } } catch (LocationForward ex) { upcall.setLocationForward(ex.ior, ex.perm); } - /* - * This can't happen in Java catch(org.omg.CORBA.UserException ex) { - * upcall.setUserException(ex); } - */ catch (SystemException ex) { upcall.setSystemException(ex); } catch (Exception ex) { handleUnknownException(upcall, ex); } - // - // Java only - // // If the skeleton has marshalled a user exception, it is now // safe to call endUserException - // - if (upcall.userException()) - upcall.endUserException(); + if (upcall.userException()) upcall.endUserException(); - // // Decrement the outstanding request count - // _OB_decrementRequestCount(); } - DirectServant _OB_getDirectServant(byte[] oid, - RefCountPolicyList policies) - throws LocationForward { - return servantLocationStrategy_.createDirectStubImpl(this, oid, - policies); + DirectServant _OB_getDirectServant(byte[] oid, RefCountPolicyList policies) throws LocationForward { + return servantLocationStrategy_.createDirectStubImpl(this, oid, policies); } public PoaCurrentImpl _OB_POACurrent() { @@ -1311,111 +1150,67 @@ public void _OB_removeDirectServant(byte[] oid, DirectServant directServant) { servantLocationStrategy_.removeDirectStubImpl(oid, directServant); } - // // Determine if this POA matches the provided object key - // - boolean _OB_poaMatches(ObjectKeyData data, - boolean full) { + boolean _OB_poaMatches(ObjectKeyData data, boolean full) { if (full) { - // // Check server id - // - if (!data.serverId.equals(serverId_)) - return false; + if (!data.serverId.equals(serverId_)) return false; - // // If the length is incorrect, return false - // - if (data.poaId.length != poaId_.length) - return false; + if (data.poaId.length != poaId_.length) return false; - // // Check each name - // for (int i = 0; i < data.poaId.length; ++i) if (!data.poaId[i].equals(poaId_[i])) return false; } - // - // Is the POA persistent? If so then the ObjectKeyData must be - // persistent. - // - if (policies_.lifespanPolicy() == LifespanPolicyValue.PERSISTENT) - return data.persistent; + // Is the POA persistent? If so then the ObjectKeyData must be persistent. + if (policies_.lifespanPolicy() == LifespanPolicyValue.PERSISTENT) return data.persistent; - // // Otherwise this POA is transient. The ObjectKeyData must be // transient, and the POA create times must be the same. - // - if (data.persistent) - return false; + if (data.persistent) return false; return data.createTime == poaCreateTime_; } - // // Increment the outstanding number of requests - // public boolean _OB_incrementRequestCount() { return poaControl_.incrementRequestCount(); } - // // Decrement the outstanding number of requests - // public void _OB_decrementRequestCount() { if (poaControl_.decrementRequestCount()) { completeDestroy(); } } - // // Wait for all pending requests to terminate - // public void _OB_waitPendingRequests() { poaControl_.waitPendingRequests(); } - // // Get the ORBInstance object - // public ORBInstance _OB_ORBInstance() { return orbInstance_; } - // // Add the policy factory for the POA Policies - // public void _OB_addPolicyFactory() { - PolicyFactoryManager pfm = orbInstance_ - .getPolicyFactoryManager(); + PolicyFactoryManager pfm = orbInstance_.getPolicyFactoryManager(); PolicyFactory factory = new POAPolicyFactory_impl(); - pfm.registerPolicyFactory( - THREAD_POLICY_ID.value, factory, true); - pfm.registerPolicyFactory( - LIFESPAN_POLICY_ID.value, factory, true); - pfm.registerPolicyFactory( - ID_UNIQUENESS_POLICY_ID.value, factory, - true); - pfm.registerPolicyFactory( - ID_ASSIGNMENT_POLICY_ID.value, factory, - true); - pfm.registerPolicyFactory( - IMPLICIT_ACTIVATION_POLICY_ID.value, - factory, true); - pfm.registerPolicyFactory( - SERVANT_RETENTION_POLICY_ID.value, - factory, true); - pfm.registerPolicyFactory( - REQUEST_PROCESSING_POLICY_ID.value, - factory, true); - pfm.registerPolicyFactory(SYNCHRONIZATION_POLICY_ID.value, factory, - true); - pfm.registerPolicyFactory(DISPATCH_STRATEGY_POLICY_ID.value, factory, - true); - pfm.registerPolicyFactory(INTERCEPTOR_CALL_POLICY_ID.value, factory, - true); + pfm.registerPolicyFactory(THREAD_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(LIFESPAN_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(ID_UNIQUENESS_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(ID_ASSIGNMENT_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(IMPLICIT_ACTIVATION_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(SERVANT_RETENTION_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(REQUEST_PROCESSING_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(SYNCHRONIZATION_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(DISPATCH_STRATEGY_POLICY_ID.value, factory, true); + pfm.registerPolicyFactory(INTERCEPTOR_CALL_POLICY_ID.value, factory, true); } public void _OB_validateManagerState() { @@ -1424,20 +1219,11 @@ public void _OB_validateManagerState() { } public void _OB_etherealize(POAManager_impl manager) { - // // Recursively etherealize children's POA - // - Enumeration e = children_.elements(); - while (e.hasMoreElements()) { - POA_impl child = (POA_impl) e - .nextElement(); - child._OB_etherealize(manager); - } + children_.values().forEach(child -> child._OB_etherealize(manager)); - // - // Eterealize our servants if the POA is assocatied with the + // Etherealize our servants if the POA is associated with the // POAManager passed in argument. - // if (manager == manager_) { servantLocationStrategy_.etherealize(this); } @@ -1447,12 +1233,10 @@ public void _OB_destroy(boolean etherealize, boolean waitForCompletion, List orts = null == templates ? childTemplates_ : templates; children_.values().stream() .filter(Objects::nonNull) .forEach(p -> p._OB_destroy(etherealize, waitForCompletion, orts)); - // // If waitForCompletion is FALSE, the destroy operation // destroys the POA and its children but waits neither for // active requests to complete nor for etherealization to @@ -1505,9 +1282,7 @@ public void _OB_destroy(boolean etherealize, boolean waitForCompletion, List 0) - _ob_right = _ob_m; - else - _ob_left = _ob_m + 1; - } - - switch (_ob_index) { - case 0: // _interface + switch (opName) { + case "_interface": { - upcall_.preUnmarshal(); - upcall_.postUnmarshal(); - org.omg.CORBA.InterfaceDef def = servant_._get_interface(); - upcall_.postinvoke(); - YokoOutputStream out = upcall_.preMarshal(); + upcall.preUnmarshal(); + upcall.postUnmarshal(); + InterfaceDef def = servant._get_interface(); + upcall.postinvoke(); + final YokoOutputStream out = upcall.preMarshal(); try { out.write_Object(def); - } catch (org.omg.CORBA.SystemException ex) { - upcall_.marshalEx(ex); + } catch (SystemException ex) { + upcall.marshalEx(ex); } - upcall_.postMarshal(); + upcall.postMarshal(); return true; } - case 1: // _is_a + case "_is_a": // _is_a { - YokoInputStream in = upcall_.preUnmarshal(); + final YokoInputStream in = upcall.preUnmarshal(); String id = null; try { id = in.read_string(); - } catch (org.omg.CORBA.SystemException ex) { - upcall_.unmarshalEx(ex); + } catch (SystemException ex) { + upcall.unmarshalEx(ex); } - upcall_.postUnmarshal(); - boolean b = servant_._is_a(id); - upcall_.postinvoke(); - YokoOutputStream out = upcall_.preMarshal(); + upcall.postUnmarshal(); + boolean b = servant._is_a(id); + upcall.postinvoke(); + final YokoOutputStream out = upcall.preMarshal(); try { out.write_boolean(b); - } catch (org.omg.CORBA.SystemException ex) { - upcall_.marshalEx(ex); + } catch (SystemException ex) { + upcall.marshalEx(ex); } - upcall_.postMarshal(); + upcall.postMarshal(); return true; } - case 2: // _non_existent + case "_non_existent": // _non_existent { - upcall_.preUnmarshal(); - upcall_.postUnmarshal(); - boolean b = servant_._non_existent(); - upcall_.postinvoke(); - YokoOutputStream out = upcall_.preMarshal(); + upcall.preUnmarshal(); + upcall.postUnmarshal(); + boolean b = servant._non_existent(); + upcall.postinvoke(); + final YokoOutputStream out = upcall.preMarshal(); try { out.write_boolean(b); - } catch (org.omg.CORBA.SystemException ex) { - upcall_.marshalEx(ex); + } catch (SystemException ex) { + upcall.marshalEx(ex); } - upcall_.postMarshal(); + upcall.postMarshal(); return true; } + default: + return false; } - - return false; } - void dispatch() throws org.apache.yoko.orb.OB.LocationForward { + void dispatch() throws LocationForward { // // Handle common operations // - if (dispatchBase()) - return; + if (dispatchBase()) return; // // Case 1: Servant is org.apache.yoko.orb.PortableServer.Servant, i.e., // a proprietary skeleton with full interceptor support // - if (servant_ instanceof org.apache.yoko.orb.PortableServer.Servant) { - org.apache.yoko.orb.PortableServer.Servant s = (org.apache.yoko.orb.PortableServer.Servant) servant_; - s._OB_dispatch(upcall_); + if (servant instanceof org.apache.yoko.orb.PortableServer.Servant) { + org.apache.yoko.orb.PortableServer.Servant s = (org.apache.yoko.orb.PortableServer.Servant) servant; + s._OB_dispatch(upcall); } // // Case 2: Servant is a org.omg.CORBA.portable.InvokeHandler, @@ -168,14 +142,14 @@ void dispatch() throws org.apache.yoko.orb.OB.LocationForward { // createExceptionReply(). SystemExceptions are raised // directly. // - else if (servant_ instanceof org.omg.CORBA.portable.InvokeHandler) { + else if (servant instanceof InvokeHandler) { try { - org.omg.CORBA.portable.InvokeHandler inv = (org.omg.CORBA.portable.InvokeHandler) servant_; + InvokeHandler inv = (InvokeHandler) servant; // // Prepare to unmarshal // - org.omg.CORBA.portable.InputStream in = upcall_.preUnmarshal(); + InputStream in = upcall.preUnmarshal(); // // Call postUnmarshal now. There may be interceptors that @@ -183,54 +157,49 @@ else if (servant_ instanceof org.omg.CORBA.portable.InvokeHandler) { // When using a portable skeleton, the interceptors cannot // obtain parameter information. // - upcall_.postUnmarshal(); + upcall.postUnmarshal(); // // Invoke the portable skeleton // - org.omg.CORBA.portable.OutputStream out = inv._invoke(upcall_ - .operation(), in, this); + OutputStream out = inv._invoke(upcall.operation(), in, this); // // The OutputStream returned by _invoke() should be // the Upcall's OutputStream // - Assert.ensure(out == upcall_ - .output()); + Assert.ensure(out == upcall.output()); // // Finish up // - if (!upcall_.userException()) - upcall_.postMarshal(); + if (!upcall.userException()) upcall.postMarshal(); } catch (Abort ex) { // // Abort is raised by createExceptionReply() // - } catch (org.apache.yoko.orb.OB.RuntimeLocationForward ex) { + } catch (RuntimeLocationForward ex) { // // RuntimeLocationForward is raised by createReply() and // createExceptionReply() to bypass the portable // skeleton and report a location-forward // - throw new org.apache.yoko.orb.OB.LocationForward(ex.ior, - ex.perm); + throw new LocationForward(ex.ior, ex.perm); } } // // Case 3: DSI // - else if (servant_ instanceof org.omg.PortableServer.DynamicImplementation) { - org.omg.PortableServer.DynamicImplementation impl = (org.omg.PortableServer.DynamicImplementation) servant_; - org.apache.yoko.orb.CORBA.ServerRequest request = new org.apache.yoko.orb.CORBA.ServerRequest( - impl, upcall_); + else if (servant instanceof DynamicImplementation) { + DynamicImplementation impl = (DynamicImplementation) servant; + ServerRequest request = new ServerRequest(impl, upcall); try { impl.invoke(request); request._OB_finishUnmarshal(); request._OB_postinvoke(); request._OB_doMarshal(); - } catch (org.omg.CORBA.SystemException ex) { + } catch (SystemException ex) { request._OB_finishUnmarshal(); throw ex; } @@ -245,11 +214,11 @@ else if (servant_ instanceof org.omg.PortableServer.DynamicImplementation) { // // Called by a portable skeleton for a normal reply // - public org.omg.CORBA.portable.OutputStream createReply() { + public OutputStream createReply() { try { - upcall_.postinvoke(); - return upcall_.preMarshal(); - } catch (org.apache.yoko.orb.OB.LocationForward ex) { + upcall.postinvoke(); + return upcall.preMarshal(); + } catch (LocationForward ex) { // // We need to raise an exception in order to abort the // current execution context and return control to @@ -260,17 +229,15 @@ public org.omg.CORBA.portable.OutputStream createReply() { // Note that the user can interfere with this process // if they trap RuntimeException. // - throw new org.apache.yoko.orb.OB.RuntimeLocationForward(ex.ior, - ex.perm); + throw new RuntimeLocationForward(ex.ior, ex.perm); } } // // Called by a portable skeleton for a user exception // - public org.omg.CORBA.portable.OutputStream createExceptionReply() { - org.omg.CORBA.portable.OutputStream out = upcall_ - .beginUserException(null); + public OutputStream createExceptionReply() { + OutputStream out = upcall.beginUserException(null); // // If the return value of beginUserException is null, then @@ -280,9 +247,7 @@ public org.omg.CORBA.portable.OutputStream createExceptionReply() { // Note that the user can interfere with this process // if they trap RuntimeException. // - if (out == null) - throw new Abort(); - else - return out; + if (out == null) throw new Abort(); + return out; } } From 8bcd9f542e0a21c089338227ac2bb7118ac74348 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Mon, 23 Feb 2026 21:41:06 +0000 Subject: [PATCH 12/18] refactor(codecs): improve Latin codec initialization and code set handling - Refactor LatinCodec to accept CodeSetInfo in constructor - Replace NAME constants with inline string literals in switch cases - Rename private interfaces from ISO_8859_X to Iso8859_X for consistency - Add static imports for CodeSetInfo constants (ISO_8859_5-9, ISO_LATIN_2-4) - Remove UTF_8 restriction in native_cs validation in ORB_impl --- .../org/apache/yoko/codecs/LatinCodec.java | 60 +++++++++++-------- .../org/apache/yoko/orb/OBCORBA/ORB_impl.java | 2 +- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java index 86a02456e..3caa03f46 100644 --- a/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java +++ b/yoko-core/src/main/java/org/apache/yoko/codecs/LatinCodec.java @@ -34,6 +34,14 @@ import static java.util.stream.IntStream.range; import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_BYTE; import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_8859_5; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_8859_6; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_8859_7; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_8859_8; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_8859_9; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_LATIN_2; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_LATIN_3; +import static org.apache.yoko.orb.OB.CodeSetInfo.ISO_LATIN_4; import static org.apache.yoko.util.Collectors.neverCombine; /** @@ -43,28 +51,28 @@ class LatinCodec implements CharCodec { static LatinCodec getLatinCodec(Charset charset) { if (!charset.canEncode()) throw new UnsupportedCharsetException(charset.name()); switch (charset.name()) { - case ISO_8859_2.NAME: return ISO_8859_2.INSTANCE; - case ISO_8859_3.NAME: return ISO_8859_3.INSTANCE; - case ISO_8859_4.NAME: return ISO_8859_4.INSTANCE; - case ISO_8859_5.NAME: return ISO_8859_5.INSTANCE; - case ISO_8859_6.NAME: return ISO_8859_6.INSTANCE; - case ISO_8859_7.NAME: return ISO_8859_7.INSTANCE; - case ISO_8859_8.NAME: return ISO_8859_8.INSTANCE; - case ISO_8859_9.NAME: return ISO_8859_9.INSTANCE; + case "ISO-8859-2": return Iso8859_2.INSTANCE; + case "ISO-8859-3": return Iso8859_3.INSTANCE; + case "ISO-8859-4": return Iso8859_4.INSTANCE; + case "ISO-8859-5": return Iso8859_5.INSTANCE; + case "ISO-8859-6": return Iso8859_6.INSTANCE; + case "ISO-8859-7": return Iso8859_7.INSTANCE; + case "ISO-8859-8": return Iso8859_8.INSTANCE; + case "ISO-8859-9": return Iso8859_9.INSTANCE; default: throw new UnsupportedCharsetException(charset.name()); } } static LatinCodec getLatinCodec(CodeSetInfo csi) { switch (csi) { - case ISO_LATIN_2: return ISO_8859_2.INSTANCE; - case ISO_LATIN_3: return ISO_8859_3.INSTANCE; - case ISO_LATIN_4: return ISO_8859_4.INSTANCE; - case ISO_8859_5: return ISO_8859_5.INSTANCE; - case ISO_8859_6: return ISO_8859_6.INSTANCE; - case ISO_8859_7: return ISO_8859_7.INSTANCE; - case ISO_8859_8: return ISO_8859_8.INSTANCE; - case ISO_8859_9: return ISO_8859_9.INSTANCE; + case ISO_LATIN_2: return Iso8859_2.INSTANCE; + case ISO_LATIN_3: return Iso8859_3.INSTANCE; + case ISO_LATIN_4: return Iso8859_4.INSTANCE; + case ISO_8859_5: return Iso8859_5.INSTANCE; + case ISO_8859_6: return Iso8859_6.INSTANCE; + case ISO_8859_7: return Iso8859_7.INSTANCE; + case ISO_8859_8: return Iso8859_8.INSTANCE; + case ISO_8859_9: return Iso8859_9.INSTANCE; } throw new UnsupportedCharsetException(csi.name()); } @@ -73,24 +81,24 @@ static LatinCodec getLatinCodec(CodeSetInfo csi) { // (e.g. if only Latin-2 is used, the others are never created.) // N.B. NAME is a compile-time constant and gets inlined so using it does not drive class initialization // whereas dereferencing INSTANCE forces initialization. (See JLS 12.4) - private interface ISO_8859_2 { String NAME = "ISO-8859-2"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_3 { String NAME = "ISO-8859-3"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_4 { String NAME = "ISO-8859-4"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_5 { String NAME = "ISO-8859-5"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_6 { String NAME = "ISO-8859-6"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_7 { String NAME = "ISO-8859-7"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_8 { String NAME = "ISO-8859-8"; LatinCodec INSTANCE = new LatinCodec(NAME); } - private interface ISO_8859_9 { String NAME = "ISO-8859-9"; LatinCodec INSTANCE = new LatinCodec(NAME); } + private interface Iso8859_2 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-2", ISO_LATIN_2); } + private interface Iso8859_3 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-3", ISO_LATIN_3); } + private interface Iso8859_4 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-4", ISO_LATIN_4); } + private interface Iso8859_5 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-5", ISO_8859_5); } + private interface Iso8859_6 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-6", ISO_8859_6); } + private interface Iso8859_7 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-7", ISO_8859_7); } + private interface Iso8859_8 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-8", ISO_8859_8); } + private interface Iso8859_9 { LatinCodec INSTANCE = new LatinCodec("ISO-8859-9", ISO_8859_9); } private final String name; private final CodeSetInfo codeSetInfo; private final char[] decoderArray; private final Map encoderMap; - private LatinCodec(String name) { + private LatinCodec(String name, CodeSetInfo csi) { Charset cs = Charset.forName(name); this.name = cs.name(); - this.codeSetInfo = CodeSetInfo.forName(name); + this.codeSetInfo = csi; ByteBuffer bytes = range(0, 256) .collect(() -> allocate(256), (bb, b) -> bb.put(b, (byte) b), neverCombine()); CharBuffer chars = cs.decode(bytes); diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java index ee37f1554..cd63ecac0 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBCORBA/ORB_impl.java @@ -896,7 +896,7 @@ private void setParameters(StringSeqHolder args, final Properties initialProps, } else if (key.equals("yoko.orb.native_cs")) { int csid = CodeSetInfo .getRegistryIdForName(value); - if (csid != 0 && csid != UTF_8.id) + if (csid != 0) nativeCs = csid; else { logger.severe("ORB.init: unknown value for yoko.orb.native_cs: " + value); From 286e0f68a9d20a5d44ec260b00bf3b9b8c5eca93 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Sat, 7 Feb 2026 22:39:21 +0000 Subject: [PATCH 13/18] fix: set input stream codecs in preUnmarshal() Ensure YokoInputStream has proper codecs before unmarshalling by extracting and applying codeset information from service contexts in preUnmarshal(). Changes: - Add codec initialization logic to Upcall.preUnmarshal(): - Detect collocated invocations (null transportInfo_) - Extract GIOP version from profile info - For collocated calls: use collocated codecs - For remote calls: extract CodeSetContext from service contexts - Parse CodeSets service context if present - Create CodecPair from negotiated char_data and wchar_data - Fall back to GIOP version defaults if no codeset context - Call in_.setCodecsAndGiopVersion() with resolved codecs - Add Optional import for cleaner null handling - Add CodeSets import for service context ID - Reorganize imports (move static imports to end) Rationale: Previously, the input stream was created without codecs, relying on lazy initialization or default behavior. This could cause issues when unmarshalling strings before codecs were properly set. By initializing codecs in preUnmarshal() based on the negotiated codesets from the service context, we ensure: 1. Collocated invocations use optimized collocated codecs 2. Remote invocations use negotiated codesets from CodeSetContext 3. Fallback to GIOP version-appropriate defaults when no negotiation 4. Codecs are set before any unmarshalling operations begin This completes the codec initialization chain: - Downcall: codecs set when creating output stream - Upcall: codecs set in preUnmarshal() before reading parameters This fix prevents potential NullPointerException or incorrect character encoding when unmarshalling string parameters in upcalls. --- .../java/org/apache/yoko/orb/OB/Upcall.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java index 4eae98cf6..b2d3a880f 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OB/Upcall.java @@ -17,14 +17,6 @@ */ package org.apache.yoko.orb.OB; -import static java.util.logging.Logger.getLogger; -import static org.apache.yoko.io.Buffer.createWriteBuffer; -import static org.apache.yoko.orb.OB.SendingContextRuntimes.SENDING_CONTEXT_RUNTIME; -import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2; - -import java.util.logging.Level; -import java.util.logging.Logger; - import org.apache.yoko.orb.CORBA.YokoInputStream; import org.apache.yoko.orb.CORBA.YokoOutputStream; import org.apache.yoko.orb.IOP.ServiceContexts; @@ -42,11 +34,21 @@ import org.omg.CORBA.SystemException; import org.omg.CORBA.UserException; import org.omg.CORBA.portable.UnknownException; +import org.omg.IOP.CodeSets; import org.omg.IOP.IOR; import org.omg.IOP.ServiceContext; import org.omg.IOP.UnknownExceptionInfo; import org.omg.PortableServer.Servant; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static java.util.logging.Logger.getLogger; +import static org.apache.yoko.io.Buffer.createWriteBuffer; +import static org.apache.yoko.orb.OB.SendingContextRuntimes.SENDING_CONTEXT_RUNTIME; +import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2; + public class Upcall { private static final Logger logger = getLogger(Upcall.class.getName()); private final ORBInstance orbInstance_; @@ -159,6 +161,18 @@ public void createOutputStream(int offset) { } public YokoInputStream preUnmarshal() { + boolean collocated = null == transportInfo_; + final GiopVersion giopVersion = GiopVersion.get(profileInfo_.major, profileInfo_.minor); + final CodecPair codecs; + if (collocated) { + codecs = CodecPair.getCollocatedCodecs(); + } else { + codecs = Optional.ofNullable(requestContexts.get(CodeSets.value)) + .map(CodeSetUtil::extractCodeSetContext) + .map(cssc -> CodecPair.create(cssc.char_data, cssc.wchar_data)) + .orElseGet(() -> CodecPair.getDefaultCodecs(giopVersion)); + } + in_.setCodecsAndGiopVersion(codecs, giopVersion); return in_; } From 4ae203d45b8603698b703a3b3c2a1c46479f91d2 Mon Sep 17 00:00:00 2001 From: Joe Chacko Date: Thu, 12 Feb 2026 11:40:00 +0000 Subject: [PATCH 14/18] refactor: make policy fields final and improve thread safety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert all POAPolicies fields to final for immutability - Refactor policy parsing from if-else chain to switch statement - Extract lock acquisition/release logic into separate methods in POA_impl - Add try-finally block to ensure locks are always released - Make ServantDispatcher fields final (upcall, servant) - Make ThreadPolicyValue fields final (value, values array) - Add POA initialization loggers (INIT_LOG, ORB_INIT_LOG, POA_INIT_LOG) - Simplify policy recreation using array initializer - Add warning logging for unsupported policy types - Clean up imports and remove unnecessary fully-qualified names - Fix typo in POA_impl comment ("used ensure" → "used to ensure") --- .../orb/OBPortableServer/POAPolicies.java | 296 +++++++++--------- .../yoko/orb/OBPortableServer/POA_impl.java | 61 ++-- .../OBPortableServer/ServantDispatcher.java | 5 +- .../omg/PortableServer/ThreadPolicyValue.java | 51 ++- .../apache/yoko/logging/VerboseLogging.java | 7 +- 5 files changed, 206 insertions(+), 214 deletions(-) diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAPolicies.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAPolicies.java index d27f08b15..830cdc543 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAPolicies.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POAPolicies.java @@ -1,5 +1,5 @@ /* - * Copyright 2010 IBM Corporation and others. + * Copyright 2026 IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,140 +17,137 @@ */ package org.apache.yoko.orb.OBPortableServer; -import org.apache.yoko.orb.OBPortableServer.DISPATCH_STRATEGY_POLICY_ID; -import org.apache.yoko.orb.OBPortableServer.DispatchStrategyPolicy; -import org.apache.yoko.orb.OBPortableServer.DispatchStrategyPolicyHelper; -import org.apache.yoko.orb.OBPortableServer.INTERCEPTOR_CALL_POLICY_ID; -import org.apache.yoko.orb.OBPortableServer.InterceptorCallPolicy; -import org.apache.yoko.orb.OBPortableServer.InterceptorCallPolicyHelper; -import org.apache.yoko.orb.OBPortableServer.SYNCHRONIZATION_POLICY_ID; -import org.apache.yoko.orb.OBPortableServer.SynchronizationPolicy; -import org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyHelper; -import org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyValue; +import org.apache.yoko.orb.OB.DispatchStrategy; +import org.apache.yoko.orb.OB.DispatchStrategyFactory; +import org.apache.yoko.orb.OB.ORBInstance; import org.apache.yoko.orb.OB.ZERO_PORT_POLICY_ID; -import org.apache.yoko.orb.OB.ZeroPortPolicy; import org.apache.yoko.orb.OB.ZeroPortPolicyHelper; -import org.apache.yoko.orb.OB.ZeroPortPolicyValue; +import org.apache.yoko.orb.PortableServer.IdAssignmentPolicy_impl; +import org.apache.yoko.orb.PortableServer.IdUniquenessPolicy_impl; +import org.apache.yoko.orb.PortableServer.ImplicitActivationPolicy_impl; +import org.apache.yoko.orb.PortableServer.LifespanPolicy_impl; +import org.apache.yoko.orb.PortableServer.RequestProcessingPolicy_impl; +import org.apache.yoko.orb.PortableServer.ServantRetentionPolicy_impl; +import org.omg.BiDirPolicy.BIDIRECTIONAL_POLICY_TYPE; +import org.omg.BiDirPolicy.BOTH; +import org.omg.BiDirPolicy.BidirectionalPolicyHelper; +import org.omg.CORBA.Policy; +import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID; +import org.omg.PortableServer.ID_UNIQUENESS_POLICY_ID; +import org.omg.PortableServer.IMPLICIT_ACTIVATION_POLICY_ID; +import org.omg.PortableServer.IdAssignmentPolicyHelper; +import org.omg.PortableServer.IdAssignmentPolicyValue; +import org.omg.PortableServer.IdUniquenessPolicyHelper; +import org.omg.PortableServer.IdUniquenessPolicyValue; +import org.omg.PortableServer.ImplicitActivationPolicyHelper; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.LIFESPAN_POLICY_ID; +import org.omg.PortableServer.LifespanPolicyHelper; +import org.omg.PortableServer.LifespanPolicyValue; +import org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID; +import org.omg.PortableServer.RequestProcessingPolicyHelper; +import org.omg.PortableServer.RequestProcessingPolicyValue; +import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; +import org.omg.PortableServer.ServantRetentionPolicyHelper; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.THREAD_POLICY_ID; +import org.omg.PortableServer.ThreadPolicyHelper; +import org.omg.PortableServer.ThreadPolicyValue; + +import static org.apache.yoko.logging.VerboseLogging.POA_INIT_LOG; +import static org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyValue.NO_SYNCHRONIZATION; +import static org.apache.yoko.orb.OBPortableServer.SynchronizationPolicyValue.SYNCHRONIZE_ON_ORB; +import static org.omg.PortableServer.IdAssignmentPolicyValue.SYSTEM_ID; +import static org.omg.PortableServer.IdUniquenessPolicyValue.UNIQUE_ID; +import static org.omg.PortableServer.ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION; +import static org.omg.PortableServer.LifespanPolicyValue.TRANSIENT; +import static org.omg.PortableServer.RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY; +import static org.omg.PortableServer.ServantRetentionPolicyValue.RETAIN; +import static org.omg.PortableServer.ThreadPolicyValue.SINGLE_THREAD_MODEL; final public class POAPolicies { - private boolean interceptorCallPolicyValue_; - - private SynchronizationPolicyValue synchronizationPolicyValue_; - - private org.apache.yoko.orb.OB.DispatchStrategy dispatchStrategyPolicyValue_; - - private boolean zeroPortPolicyValue_; - - private org.omg.PortableServer.LifespanPolicyValue lifespanPolicyValue_; - - private org.omg.PortableServer.IdUniquenessPolicyValue idUniquenessPolicyValue_; - - private org.omg.PortableServer.IdAssignmentPolicyValue idAssignmentPolicyValue_; - - private org.omg.PortableServer.ImplicitActivationPolicyValue implicitActivationPolicyValue_; - - private org.omg.PortableServer.ServantRetentionPolicyValue servantRetentionPolicyValue_; - - private org.omg.PortableServer.RequestProcessingPolicyValue requestProcessingPolicyValue_; - - private short bidirPolicyValue_; - - POAPolicies(org.apache.yoko.orb.OB.ORBInstance orbInstance, - org.omg.CORBA.Policy[] policies) { - // - // Set the default policy values - // - interceptorCallPolicyValue_ = true; - synchronizationPolicyValue_ = SynchronizationPolicyValue.NO_SYNCHRONIZATION; - zeroPortPolicyValue_ = false; - lifespanPolicyValue_ = org.omg.PortableServer.LifespanPolicyValue.TRANSIENT; - idUniquenessPolicyValue_ = org.omg.PortableServer.IdUniquenessPolicyValue.UNIQUE_ID; - idAssignmentPolicyValue_ = org.omg.PortableServer.IdAssignmentPolicyValue.SYSTEM_ID; - implicitActivationPolicyValue_ = org.omg.PortableServer.ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION; - servantRetentionPolicyValue_ = org.omg.PortableServer.ServantRetentionPolicyValue.RETAIN; - requestProcessingPolicyValue_ = org.omg.PortableServer.RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY; - dispatchStrategyPolicyValue_ = null; - bidirPolicyValue_ = org.omg.BiDirPolicy.BOTH.value; + private final boolean interceptorCallPolicy; + private final SynchronizationPolicyValue synchronizationPolicy; + private final DispatchStrategy dispatchStrategyPolicy; + private final boolean zeroPortPolicy; + private final LifespanPolicyValue lifespanPolicy; + private final IdUniquenessPolicyValue idUniquenessPolicy; + private final IdAssignmentPolicyValue idAssignmentPolicy; + private final ImplicitActivationPolicyValue implicitActivationPolicy; + private final ServantRetentionPolicyValue servantRetentionPolicy; + private final RequestProcessingPolicyValue requestProcessingPolicy; + private final short bidirPolicyValue; + + POAPolicies(ORBInstance orbInstance, Policy[] policies) { + // Set the default policy values. + // These are temporary variables to allow the final fields to be set after the for loop. + // TODO: refactor to use a builder pattern for conciseness + boolean interceptorCall = true; + SynchronizationPolicyValue synchronization = null; + ThreadPolicyValue thread = null; + boolean zeroPort = false; + LifespanPolicyValue lifespan = TRANSIENT; + IdUniquenessPolicyValue idUniqueness = UNIQUE_ID; + IdAssignmentPolicyValue idAssignment = SYSTEM_ID; + ImplicitActivationPolicyValue implicitActivation = NO_IMPLICIT_ACTIVATION; + ServantRetentionPolicyValue servantRetention = RETAIN; + RequestProcessingPolicyValue requestProcessing = USE_ACTIVE_OBJECT_MAP_ONLY; + DispatchStrategy dispatchStrategy = null; + short bidir = BOTH.value; if (policies != null) { - for (int i = 0; i < policies.length; ++i) { - int policyType = policies[i].policy_type(); - if (policyType == org.omg.PortableServer.THREAD_POLICY_ID.value) { - org.omg.PortableServer.ThreadPolicy policy = org.omg.PortableServer.ThreadPolicyHelper - .narrow(policies[i]); - synchronizationPolicyValue_ = (policy.value() == org.omg.PortableServer.ThreadPolicyValue.ORB_CTRL_MODEL) ? SynchronizationPolicyValue.NO_SYNCHRONIZATION - : SynchronizationPolicyValue.SYNCHRONIZE_ON_ORB; - } else if (policyType == org.omg.PortableServer.LIFESPAN_POLICY_ID.value) { - org.omg.PortableServer.LifespanPolicy policy = org.omg.PortableServer.LifespanPolicyHelper - .narrow(policies[i]); - lifespanPolicyValue_ = policy.value(); - } else if (policyType == org.omg.PortableServer.ID_UNIQUENESS_POLICY_ID.value) { - org.omg.PortableServer.IdUniquenessPolicy policy = org.omg.PortableServer.IdUniquenessPolicyHelper - .narrow(policies[i]); - idUniquenessPolicyValue_ = policy.value(); - } else if (policyType == org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID.value) { - org.omg.PortableServer.IdAssignmentPolicy policy = org.omg.PortableServer.IdAssignmentPolicyHelper - .narrow(policies[i]); - idAssignmentPolicyValue_ = policy.value(); - } else if (policyType == org.omg.PortableServer.IMPLICIT_ACTIVATION_POLICY_ID.value) { - org.omg.PortableServer.ImplicitActivationPolicy policy = org.omg.PortableServer.ImplicitActivationPolicyHelper - .narrow(policies[i]); - implicitActivationPolicyValue_ = policy.value(); - } else if (policyType == org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID.value) { - org.omg.PortableServer.ServantRetentionPolicy policy = org.omg.PortableServer.ServantRetentionPolicyHelper - .narrow(policies[i]); - servantRetentionPolicyValue_ = policy.value(); - } else if (policyType == org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID.value) { - org.omg.PortableServer.RequestProcessingPolicy policy = org.omg.PortableServer.RequestProcessingPolicyHelper - .narrow(policies[i]); - requestProcessingPolicyValue_ = policy.value(); - } else if (policyType == org.omg.BiDirPolicy.BIDIRECTIONAL_POLICY_TYPE.value) { - org.omg.BiDirPolicy.BidirectionalPolicy p = org.omg.BiDirPolicy.BidirectionalPolicyHelper - .narrow(policies[i]); - bidirPolicyValue_ = p.value(); - } - - // - // Yoko proprietary policies - // - else if (policyType == SYNCHRONIZATION_POLICY_ID.value) { - SynchronizationPolicy policy = SynchronizationPolicyHelper - .narrow(policies[i]); - synchronizationPolicyValue_ = policy.value(); - } else if (policyType == DISPATCH_STRATEGY_POLICY_ID.value) { - DispatchStrategyPolicy policy = DispatchStrategyPolicyHelper - .narrow(policies[i]); - dispatchStrategyPolicyValue_ = policy.value(); - } else if (policyType == INTERCEPTOR_CALL_POLICY_ID.value) { - InterceptorCallPolicy policy = InterceptorCallPolicyHelper - .narrow(policies[i]); - interceptorCallPolicyValue_ = policy.value(); - } else if (policyType == ZERO_PORT_POLICY_ID.value) { - ZeroPortPolicy policy = ZeroPortPolicyHelper - .narrow(policies[i]); - zeroPortPolicyValue_ = policy.value(); + for (Policy policy : policies) { + switch (policy.policy_type()) { + // CORBA standard policies + case THREAD_POLICY_ID.value: thread = ThreadPolicyHelper.narrow(policy).value(); break; + case LIFESPAN_POLICY_ID.value: lifespan = LifespanPolicyHelper.narrow(policy).value(); break; + case ID_UNIQUENESS_POLICY_ID.value: idUniqueness = IdUniquenessPolicyHelper.narrow(policy).value(); break; + case ID_ASSIGNMENT_POLICY_ID.value: idAssignment = IdAssignmentPolicyHelper.narrow(policy).value(); break; + case IMPLICIT_ACTIVATION_POLICY_ID.value: implicitActivation = ImplicitActivationPolicyHelper.narrow(policy).value(); break; + case SERVANT_RETENTION_POLICY_ID.value: servantRetention = ServantRetentionPolicyHelper.narrow(policy).value(); break; + case REQUEST_PROCESSING_POLICY_ID.value: requestProcessing = RequestProcessingPolicyHelper.narrow(policy).value(); break; + case BIDIRECTIONAL_POLICY_TYPE.value: bidir = BidirectionalPolicyHelper.narrow(policy).value(); break; + // Yoko proprietary policies + case SYNCHRONIZATION_POLICY_ID.value: synchronization = SynchronizationPolicyHelper.narrow(SynchronizationPolicyHelper.narrow(policy)).value(); break; + case DISPATCH_STRATEGY_POLICY_ID.value: dispatchStrategy = DispatchStrategyPolicyHelper.narrow(DispatchStrategyPolicyHelper.narrow(policy)).value(); break; + case INTERCEPTOR_CALL_POLICY_ID.value: interceptorCall = InterceptorCallPolicyHelper.narrow(InterceptorCallPolicyHelper.narrow(policy)).value(); break; + case ZERO_PORT_POLICY_ID.value: zeroPort = ZeroPortPolicyHelper.narrow(ZeroPortPolicyHelper.narrow(policy)).value(); break; + default: + // Unknown policy + POA_INIT_LOG.warning(String.format("Ignoring unsupported policy of type 0x%x", policy.policy_type())); } - - // - // Otherwise the policy is not a ORB defined POA policy - // } } - if (dispatchStrategyPolicyValue_ == null) { - org.apache.yoko.orb.OB.DispatchStrategyFactory dsf = orbInstance - .getDispatchStrategyFactory(); - dispatchStrategyPolicyValue_ = dsf - .create_default_dispatch_strategy(); + zeroPortPolicy = zeroPort; + interceptorCallPolicy = interceptorCall; + bidirPolicyValue = bidir; + requestProcessingPolicy = requestProcessing; + servantRetentionPolicy = servantRetention; + implicitActivationPolicy = implicitActivation; + idAssignmentPolicy = idAssignment; + idUniquenessPolicy = idUniqueness; + lifespanPolicy = lifespan; + // the synchronization policy can be set explicitly (proprietary), or derived from the thread policy (standard) + if (null == synchronization) { + // only consider the thread policy if there was no explicit synchronization policy + synchronizationPolicy = SINGLE_THREAD_MODEL == thread ? SYNCHRONIZE_ON_ORB : NO_SYNCHRONIZATION; + } else { + synchronizationPolicy = synchronization; } + if (dispatchStrategy == null) { + DispatchStrategyFactory dsf = orbInstance.getDispatchStrategyFactory(); + dispatchStrategy = dsf.create_default_dispatch_strategy(); + } + dispatchStrategyPolicy = dispatchStrategy; } public boolean interceptorCallPolicy() { - return interceptorCallPolicyValue_; + return interceptorCallPolicy; } public boolean zeroPortPolicy() { - return zeroPortPolicyValue_; + return zeroPortPolicy; } public SynchronizationPolicyValue synchronizationPolicy() { @@ -159,42 +156,42 @@ public SynchronizationPolicyValue synchronizationPolicy() { // ORBORB_impl.ServerConcModelThreaded) // return org.apache.yoko.orb.OB.SYNCHRONIZE_ON_ORB; - return synchronizationPolicyValue_; + return synchronizationPolicy; } - public org.apache.yoko.orb.OB.DispatchStrategy dispatchStrategyPolicy() { - return dispatchStrategyPolicyValue_; + public DispatchStrategy dispatchStrategyPolicy() { + return dispatchStrategyPolicy; } - public org.omg.PortableServer.LifespanPolicyValue lifespanPolicy() { - return lifespanPolicyValue_; + public LifespanPolicyValue lifespanPolicy() { + return lifespanPolicy; } - public org.omg.PortableServer.IdUniquenessPolicyValue idUniquenessPolicy() { - return idUniquenessPolicyValue_; + public IdUniquenessPolicyValue idUniquenessPolicy() { + return idUniquenessPolicy; } - public org.omg.PortableServer.IdAssignmentPolicyValue idAssignmentPolicy() { - return idAssignmentPolicyValue_; + public IdAssignmentPolicyValue idAssignmentPolicy() { + return idAssignmentPolicy; } - public org.omg.PortableServer.ImplicitActivationPolicyValue implicitActivationPolicy() { - return implicitActivationPolicyValue_; + public ImplicitActivationPolicyValue implicitActivationPolicy() { + return implicitActivationPolicy; } - public org.omg.PortableServer.ServantRetentionPolicyValue servantRetentionPolicy() { - return servantRetentionPolicyValue_; + public ServantRetentionPolicyValue servantRetentionPolicy() { + return servantRetentionPolicy; } - public org.omg.PortableServer.RequestProcessingPolicyValue requestProcessingPolicy() { - return requestProcessingPolicyValue_; + public RequestProcessingPolicyValue requestProcessingPolicy() { + return requestProcessingPolicy; } public short bidirPolicy() { - return bidirPolicyValue_; + return bidirPolicyValue; } - public org.omg.CORBA.Policy[] recreate() { + public Policy[] recreate() { // // TODO: // @@ -204,24 +201,17 @@ public org.omg.CORBA.Policy[] recreate() { // provided. Also, providing both Sync policy and ThreadPolicy // should be invalid. // - org.omg.CORBA.Policy[] pl = new org.omg.CORBA.Policy[10]; - int i = 0; - pl[i++] = new org.apache.yoko.orb.PortableServer.LifespanPolicy_impl( - lifespanPolicyValue_); - pl[i++] = new org.apache.yoko.orb.PortableServer.IdUniquenessPolicy_impl( - idUniquenessPolicyValue_); - pl[i++] = new org.apache.yoko.orb.PortableServer.IdAssignmentPolicy_impl( - idAssignmentPolicyValue_); - pl[i++] = new org.apache.yoko.orb.PortableServer.ImplicitActivationPolicy_impl( - implicitActivationPolicyValue_); - pl[i++] = new org.apache.yoko.orb.PortableServer.ServantRetentionPolicy_impl( - servantRetentionPolicyValue_); - pl[i++] = new org.apache.yoko.orb.PortableServer.RequestProcessingPolicy_impl( - requestProcessingPolicyValue_); - pl[i++] = new SynchronizationPolicy_impl(synchronizationPolicyValue_); - pl[i++] = new DispatchStrategyPolicy_impl(dispatchStrategyPolicyValue_); - pl[i] = new InterceptorCallPolicy_impl(interceptorCallPolicyValue_); - + Policy[] pl = { + new LifespanPolicy_impl(lifespanPolicy), + new IdUniquenessPolicy_impl(idUniquenessPolicy), + new IdAssignmentPolicy_impl(idAssignmentPolicy), + new ImplicitActivationPolicy_impl(implicitActivationPolicy), + new ServantRetentionPolicy_impl(servantRetentionPolicy), + new RequestProcessingPolicy_impl(requestProcessingPolicy), + new SynchronizationPolicy_impl(synchronizationPolicy), + new DispatchStrategyPolicy_impl(dispatchStrategyPolicy), + new InterceptorCallPolicy_impl(interceptorCallPolicy), + }; return pl; } } diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java index 7ff36f25a..e4f846617 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/POA_impl.java @@ -171,7 +171,7 @@ final public class POA_impl extends LocalObject implements POA { private final POAPolicies policies_; private final IdGenerationStrategy idGenerationStrategy_; private final int poaCreateTime_; - /** If this POA has the single thread policy set then this mutex is used ensure this policy is met */ + /** If this POA has the single thread policy set then this mutex is used to ensure this policy is met */ private final RecursiveMutex poaSyncMutex_ = new RecursiveMutex(); private final DispatchStrategy dispatchStrategy_; private final PoaCurrentImpl poaCurrent_; @@ -963,7 +963,10 @@ public void _OB_preinvoke(String op, byte[] oid, Servant servant, Object cookie, poaCurrent_._OB_preinvoke(this, servant, op, oid, cookie); // Depending on the synchronization policy we have to lock a variety of mutexes. - // TODO: DUMP THIS IF POSSIBLE + getLock(); + } + + private void getLock() { switch (policies_.synchronizationPolicy().value()) { case _NO_SYNCHRONIZATION: break; @@ -977,42 +980,48 @@ public void _OB_preinvoke(String op, byte[] oid, Servant servant, Object cookie, } public void _OB_postinvoke() { - byte[] oid = poaCurrent_._OB_getObjectId(); - String op = poaCurrent_._OB_getOp(); - Servant servant = poaCurrent_._OB_getServant(); - Object cookie = poaCurrent_._OB_getCookie(); - // Depending on the synchronization policy we have to unlock a - // variety of mutexes. Note that we have to do this before - // calling postinvoke else we might operate on a destroyed - // servant. - switch (policies_.synchronizationPolicy().value()) { - case _NO_SYNCHRONIZATION: - break; - case _SYNCHRONIZE_ON_POA: - poaSyncMutex_.unlock(); - break; - case _SYNCHRONIZE_ON_ORB: - orbInstance_.getORBSyncMutex().unlock(); - break; - } + byte[] oid; + String op; + Servant servant; + Object cookie; - // + // use a try-finally to ensure unlocking happens even if these getters throw + try { + oid = poaCurrent_._OB_getObjectId(); + op = poaCurrent_._OB_getOp(); + servant = poaCurrent_._OB_getServant(); + cookie = poaCurrent_._OB_getCookie(); + } finally { + releaseLock(); + } // Clean up the PortableServant::Current - // poaCurrent_._OB_postinvoke(); - // // Clean up the OCI:Current - // ociCurrent_._OB_postinvoke(); - // // postinvoke the servant location strategy - // servantLocationStrategy_.postinvoke(oid, this, op, cookie, servant); } + private void releaseLock() { + // Depending on the synchronization policy we have to unlock a + // variety of mutexes. Note that we have to do this before + // calling postinvoke else we might operate on a destroyed + // servant. + switch (policies_.synchronizationPolicy().value()) { + case _NO_SYNCHRONIZATION: + break; + case _SYNCHRONIZE_ON_POA: + poaSyncMutex_.unlock(); + break; + case _SYNCHRONIZE_ON_ORB: + orbInstance_.getORBSyncMutex().unlock(); + break; + } + } + void _OB_locateServant(byte[] oid) throws LocationForward { CookieHolder cookieHolder = new CookieHolder(); String op = "_locate"; diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/ServantDispatcher.java b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/ServantDispatcher.java index f6acb6c69..1c64a9121 100644 --- a/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/ServantDispatcher.java +++ b/yoko-core/src/main/java/org/apache/yoko/orb/OBPortableServer/ServantDispatcher.java @@ -46,9 +46,8 @@ // standard ResponseHandler interface. // final class ServantDispatcher implements org.omg.CORBA.portable.ResponseHandler { - private Upcall upcall; - - private Servant servant; + private final Upcall upcall; + private final Servant servant; // Used to bypass a portable skeleton private static class Abort extends RuntimeException {} diff --git a/yoko-spec-corba/src/main/java/org/omg/PortableServer/ThreadPolicyValue.java b/yoko-spec-corba/src/main/java/org/omg/PortableServer/ThreadPolicyValue.java index f4f889de0..ae717125d 100644 --- a/yoko-spec-corba/src/main/java/org/omg/PortableServer/ThreadPolicyValue.java +++ b/yoko-spec-corba/src/main/java/org/omg/PortableServer/ThreadPolicyValue.java @@ -1,4 +1,6 @@ /* + * Copyright 2026 IBM Corporation and others. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,47 +17,34 @@ */ package org.omg.PortableServer; -// // IDL:omg.org/PortableServer/ThreadPolicyValue:1.0 -// -/***/ -public class ThreadPolicyValue implements org.omg.CORBA.portable.IDLEntity -{ - private static ThreadPolicyValue [] values_ = new ThreadPolicyValue[2]; - private int value_; +import org.omg.CORBA.BAD_PARAM; + +import java.io.ObjectStreamException; +import static org.omg.CORBA.CompletionStatus.COMPLETED_NO; + +public class ThreadPolicyValue implements org.omg.CORBA.portable.IDLEntity { public final static int _ORB_CTRL_MODEL = 0; public final static ThreadPolicyValue ORB_CTRL_MODEL = new ThreadPolicyValue(_ORB_CTRL_MODEL); public final static int _SINGLE_THREAD_MODEL = 1; public final static ThreadPolicyValue SINGLE_THREAD_MODEL = new ThreadPolicyValue(_SINGLE_THREAD_MODEL); - protected - ThreadPolicyValue(int value) - { - values_[value] = this; - value_ = value; - } + private static final ThreadPolicyValue [] values = {ORB_CTRL_MODEL, SINGLE_THREAD_MODEL}; + private final int value; - public int - value() - { - return value_; - } + protected ThreadPolicyValue(int value) { this.value = value; } - public static ThreadPolicyValue - from_int(int value) - { - if(value < values_.length) - return values_[value]; - else - throw new org.omg.CORBA.BAD_PARAM("Value (" + value + ") out of range", 25, org.omg.CORBA.CompletionStatus.COMPLETED_NO); - } + public int value() { return value; } - private java.lang.Object - readResolve() - throws java.io.ObjectStreamException - { - return from_int(value()); + public static ThreadPolicyValue from_int(int value) { + try { + return values[value]; + } catch (ArrayIndexOutOfBoundsException e) { + throw new BAD_PARAM("Value (" + value + ") out of range", 25, COMPLETED_NO); + } } + + private Object readResolve() throws ObjectStreamException { return from_int(value()); } } diff --git a/yoko-util/src/main/java/org/apache/yoko/logging/VerboseLogging.java b/yoko-util/src/main/java/org/apache/yoko/logging/VerboseLogging.java index 90cafde25..0cf3bd8cb 100644 --- a/yoko-util/src/main/java/org/apache/yoko/logging/VerboseLogging.java +++ b/yoko-util/src/main/java/org/apache/yoko/logging/VerboseLogging.java @@ -54,6 +54,12 @@ public enum VerboseLogging { */ public static final Logger ROOT_LOG = Logger.getLogger("yoko.verbose"); + /** Log ORB initialization */ + public static final Logger INIT_LOG = Logger.getLogger("yoko.verbose.init"); + public static final Logger ORB_INIT_LOG = Logger.getLogger("yoko.verbose.init.orb"); + public static final Logger POA_INIT_LOG = Logger.getLogger("yoko.verbose.init.poa"); + + /** Connection logging:
      * CONFIG: timeout settings etc.
      * FINE:   open/accept/close connection to/from endpoint
@@ -75,7 +81,6 @@ public enum VerboseLogging {
     /** Log data sent */
     public static final Logger DATA_OUT_LOG = Logger.getLogger("yoko.verbose.data.out");
 
-
     public static final Logger RETRY_LOG = Logger.getLogger("yoko.verbose.retry");
 
     /** IOR logging: 

From 4984df3fd7bdd4ca68af51c4ea0db3c2e9032d4f Mon Sep 17 00:00:00 2001
From: Joe Chacko 
Date: Fri, 13 Feb 2026 16:36:13 +0000
Subject: [PATCH 15/18] test: migrate CodeSets test to testify framework

Migrate the legacy CodeSets test from old server/client pattern to the
modern testify framework with JUnit 5.

- Create new CodeSetsTest using @ConfigureServer annotation
- Move test files from src/test/java to src/test/java-testify
- Replace separate Server/Client classes with unified test class
- Convert test methods to JUnit 5 @Test annotations
- Use Bus for IOR sharing between server and client
- Remove legacy test infrastructure (runtest script, CodeSetsTest.java)
- Simplify test setup with @BeforeServer and @BeforeAll hooks
- Add comprehensive test classes for all ISO-8859-1 through ISO-8859-9 character sets
- Test same character set on both client and server (CodeSet1Test through CodeSet9Test)
- Test different character sets between client and server (CodeSets12Test through CodeSets91Test)
- Test client with Latin charset and server with default UTF-8 (CodeSets1DTest through CodeSets9DTest)
- Test server with Latin charset and client with default UTF-8 (CodeSetsD1Test through CodeSetsD9Test)

The new test maintains the same coverage (char, string, wchar, wstring)
while using modern testing patterns and eliminating boilerplate code.
---
 .../org/apache/yoko/CodeSetsTest.java         |  98 +++++++++++
 .../test/codesets/TestCodeSets.idl            |   0
 .../test/codesets/TestCodeSets.java           |   0
 .../test/codesets/TestCodeSetsHelper.java     |   0
 .../test/codesets/TestCodeSetsHolder.java     |   0
 .../test/codesets/TestCodeSetsOperations.java |   0
 .../test/codesets/TestCodeSetsPOA.java        |   0
 .../test/codesets/TestCodeSetsPOATie.java     |   0
 .../test/codesets/TestCodeSets_impl.java      |  12 +-
 .../test/codesets/_TestCodeSetsStub.java      |   0
 .../java/org/apache/yoko/CodeSetTest.java     |  60 -------
 .../src/test/java/test/codesets/Client.java   |  91 -----------
 .../src/test/java/test/codesets/Server.java   | 105 ------------
 .../src/test/java/test/codesets/runtest       | 152 ------------------
 14 files changed, 105 insertions(+), 413 deletions(-)
 create mode 100644 yoko-verify/src/test/java-testify/org/apache/yoko/CodeSetsTest.java
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSets.idl (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSets.java (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSetsHelper.java (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSetsHolder.java (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSetsOperations.java (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSetsPOA.java (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSetsPOATie.java (100%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/TestCodeSets_impl.java (79%)
 rename yoko-verify/src/test/{java => java-testify}/test/codesets/_TestCodeSetsStub.java (100%)
 delete mode 100644 yoko-verify/src/test/java/org/apache/yoko/CodeSetTest.java
 delete mode 100644 yoko-verify/src/test/java/test/codesets/Client.java
 delete mode 100644 yoko-verify/src/test/java/test/codesets/Server.java
 delete mode 100644 yoko-verify/src/test/java/test/codesets/runtest

diff --git a/yoko-verify/src/test/java-testify/org/apache/yoko/CodeSetsTest.java b/yoko-verify/src/test/java-testify/org/apache/yoko/CodeSetsTest.java
new file mode 100644
index 000000000..e25752cd3
--- /dev/null
+++ b/yoko-verify/src/test/java-testify/org/apache/yoko/CodeSetsTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2026 IBM Corporation and others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an \"AS IS\" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package org.apache.yoko;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.omg.CORBA.ORB;
+import test.codesets.TestCodeSets;
+import test.codesets.TestCodeSetsHelper;
+import test.codesets.TestCodeSets_impl;
+import testify.bus.Bus;
+import testify.bus.key.TypeKey;
+import testify.iiop.annotation.ConfigureOrb;
+import testify.iiop.annotation.ConfigureServer;
+import testify.iiop.annotation.ConfigureServer.BeforeServer;
+
+import static org.apache.yoko.CodeSetsTest.PublishStub.REF;
+
+@ConfigureServer
+public class CodeSetsTest {
+    // same latin codeset on server and client
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-1"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-1"})) public static class CodeSet1Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-2"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-2"})) public static class CodeSet2Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-3"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-3"})) public static class CodeSet3Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-4"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-4"})) public static class CodeSet4Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-5"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-5"})) public static class CodeSet5Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-6"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-6"})) public static class CodeSet6Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-7"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-7"})) public static class CodeSet7Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-8"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-8"})) public static class CodeSet8Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-9"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-9"})) public static class CodeSet9Test extends CodeSetsTest {}
+    // different latin codesets on server and client
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-1"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-2"})) public static class CodeSets12Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-2"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-3"})) public static class CodeSets23Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-3"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-4"})) public static class CodeSets34Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-4"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-5"})) public static class CodeSets45Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-5"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-6"})) public static class CodeSets56Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-6"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-7"})) public static class CodeSets67Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-7"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-8"})) public static class CodeSets78Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-8"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-9"})) public static class CodeSets89Test extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-9"}), serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-1"})) public static class CodeSets91Test extends CodeSetsTest {}
+    // server uses default (UTF-8)
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-1"})) public static class CodeSets1DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-2"})) public static class CodeSets2DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-3"})) public static class CodeSets3DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-4"})) public static class CodeSets4DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-5"})) public static class CodeSets5DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-6"})) public static class CodeSets6DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-7"})) public static class CodeSets7DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-8"})) public static class CodeSets8DTest extends CodeSetsTest {}
+    @ConfigureServer (clientOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-9"})) public static class CodeSets9DTest extends CodeSetsTest {}
+    // client uses default (UTF-8)
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-1"})) public static class CodeSetsD1Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-2"})) public static class CodeSetsD2Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-3"})) public static class CodeSetsD3Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-4"})) public static class CodeSetsD4Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-5"})) public static class CodeSetsD5Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-6"})) public static class CodeSetsD6Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-7"})) public static class CodeSetsD7Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-8"})) public static class CodeSetsD8Test extends CodeSetsTest {}
+    @ConfigureServer (serverOrb = @ConfigureOrb(args = {"-ORBnative_cs", "8859-9"})) public static class CodeSetsD9Test extends CodeSetsTest {}
+
+    enum PublishStub implements TypeKey {REF}
+    private static TestCodeSets stub;
+
+    @BeforeServer
+    public static void exportObject(ORB orb, Bus bus) {
+        TestCodeSets_impl impl = new TestCodeSets_impl(null);
+        TestCodeSets tcs = impl._this(orb);
+        String ior = orb.object_to_string(tcs);
+        bus.put(REF, ior);
+    }
+
+    @BeforeAll
+    public static void retrieveStub(ORB orb, Bus bus) {
+        stub = TestCodeSetsHelper.narrow(orb.string_to_object(bus.get(REF)));
+    }
+
+    @Test void testChar() { Assertions.assertEquals('a', stub.testChar('a')); }
+    @Test void testString() { Assertions.assertEquals("Hello, world", stub.testString("Hello, world")); }
+    @Test void testWchar() { Assertions.assertEquals((char) 0x1234, stub.testWChar((char) 0x1234)); }
+    @Test void testWstring() { Assertions.assertEquals("Hello, world", stub.testWString("Hello, world")); }
+}
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSets.idl b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSets.idl
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSets.idl
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSets.idl
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSets.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSets.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSets.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSets.java
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSetsHelper.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsHelper.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSetsHelper.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsHelper.java
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSetsHolder.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsHolder.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSetsHolder.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsHolder.java
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSetsOperations.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsOperations.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSetsOperations.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsOperations.java
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSetsPOA.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsPOA.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSetsPOA.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsPOA.java
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSetsPOATie.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsPOATie.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSetsPOATie.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSetsPOATie.java
diff --git a/yoko-verify/src/test/java/test/codesets/TestCodeSets_impl.java b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSets_impl.java
similarity index 79%
rename from yoko-verify/src/test/java/test/codesets/TestCodeSets_impl.java
rename to yoko-verify/src/test/java-testify/test/codesets/TestCodeSets_impl.java
index bf9c32be9..3fdd2e3da 100644
--- a/yoko-verify/src/test/java/test/codesets/TestCodeSets_impl.java
+++ b/yoko-verify/src/test/java-testify/test/codesets/TestCodeSets_impl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,10 +17,12 @@
  */
 package test.codesets;
 
-class TestCodeSets_impl extends TestCodeSetsPOA {
-    private org.omg.CORBA.ORB orb_;
+import org.omg.CORBA.ORB;
 
-    TestCodeSets_impl(org.omg.CORBA.ORB orb) {
+public class TestCodeSets_impl extends TestCodeSetsPOA {
+    private ORB orb_;
+
+    public TestCodeSets_impl(ORB orb) {
         orb_ = orb;
     }
 
@@ -41,6 +43,6 @@ public String testWString(String ws) {
     }
 
     public void deactivate() {
-        orb_.shutdown(false);
+        if (null != orb_) orb_.shutdown(false);
     }
 }
diff --git a/yoko-verify/src/test/java/test/codesets/_TestCodeSetsStub.java b/yoko-verify/src/test/java-testify/test/codesets/_TestCodeSetsStub.java
similarity index 100%
rename from yoko-verify/src/test/java/test/codesets/_TestCodeSetsStub.java
rename to yoko-verify/src/test/java-testify/test/codesets/_TestCodeSetsStub.java
diff --git a/yoko-verify/src/test/java/org/apache/yoko/CodeSetTest.java b/yoko-verify/src/test/java/org/apache/yoko/CodeSetTest.java
deleted file mode 100644
index afc4feab5..000000000
--- a/yoko-verify/src/test/java/org/apache/yoko/CodeSetTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2019 IBM Corporation and others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an \"AS IS\" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-package org.apache.yoko;
-
-import test.codesets.Client;
-import test.codesets.Server;
-
-public class CodeSetTest extends AbstractOrbTestBase {
-    private static final Class SERVER_CLASS = Server.class;
-    private static final Class CLIENT_CLASS = Client.class;
-    private static final String OUTPUT_FILE = "TestCodeSets.ref";
-
-    public void setUp() throws Exception {
-        super.setUp();
-        setWaitForFile(OUTPUT_FILE);
-    }
-        
-    public void testStandardCodeSet() throws Exception {
-        runServerClientTest(SERVER_CLASS, CLIENT_CLASS);
-    }
-        
-    public void testStandardCodeSet_11() throws Exception {
-        runServerClientTest(SERVER_CLASS, new String[] {"-OAversion", "1.1"}, CLIENT_CLASS, new String[0]);
-    }
-        
-    public void testCodeSet8859_5() throws Exception {
-        String[] args = {"-ORBnative_cs", "ISO/IEC",  "8859-5" };
-        runServerClientTest(SERVER_CLASS, args, CLIENT_CLASS, args);
-    }
-        
-    public void testCodeSet8859_5_11() throws Exception {
-        runServerClientTest(SERVER_CLASS, new String[] {"-ORBnative_cs", "ISO/IEC", "8859-5"}, 
-                            CLIENT_CLASS, new String[] {"-ORBnative_cs", "ISO/IEC", "8859-5", "-OAversion", "1.1" });
-    }
-        
-    public void testCodeSet8859_1_vs_8859_4() throws Exception {
-        runServerClientTest(SERVER_CLASS, new String[] {"-ORBnative_cs", "ISO/IEC", "8859-4"},
-                            CLIENT_CLASS, new String[] {"-ORBnative_cs", "ISO/IEC", "8859-1" });
-    }
-        
-    public void testCodeSet8859_1_vs_8859_4_11() throws Exception {
-        runServerClientTest(SERVER_CLASS, new String[] {"-ORBnative_cs", "ISO/IEC", "8859-4", "-OAversion", "1.1"},
-                            CLIENT_CLASS, new String[] {"-ORBnative_cs", "ISO/IEC", "8859-1"});
-    }
-}
diff --git a/yoko-verify/src/test/java/test/codesets/Client.java b/yoko-verify/src/test/java/test/codesets/Client.java
deleted file mode 100644
index 4a2163e37..000000000
--- a/yoko-verify/src/test/java/test/codesets/Client.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2021 IBM Corporation and others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an \"AS IS\" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-package test.codesets;
-
-import java.util.Properties;
-
-import org.apache.yoko.util.Assert;
-import org.omg.CORBA.*;
-
-final public class Client {
-    public static int run(ORB orb, String[] args)
-            throws org.omg.CORBA.UserException {
-        org.omg.CORBA.Object obj = orb
-                .string_to_object("relfile:TestCodeSets.ref");
-        if (obj == null) {
-            System.out.println("Can't read IOR from TestCodeSets.ref");
-            return 0;
-        }
-
-        TestCodeSets p = TestCodeSetsHelper.narrow(obj);
-        Assert.ensure(p != null);
-
-        {
-            char wc, wcRet;
-
-            wc = 'a';
-            wcRet = p.testWChar(wc);
-            Assert.ensure(wc == wcRet);
-
-            wc = (char) 0x1234;
-            wcRet = p.testWChar(wc);
-            Assert.ensure(wc == wcRet);
-        }
-
-        {
-            String ws, wsRet;
-
-            ws = "Hello, World!";
-            wsRet = p.testWString(ws);
-            Assert.ensure(ws.equals(wsRet));
-        }
-
-        p.deactivate();
-
-        return 0;
-    }
-
-    public static void main(String[] args) {
-        java.util.Properties props = new Properties();
-        props.putAll(System.getProperties());
-        props.put("org.omg.CORBA.ORBClass", "org.apache.yoko.orb.CORBA.ORB");
-        props.put("org.omg.CORBA.ORBSingletonClass",
-                "org.apache.yoko.orb.CORBA.ORBSingleton");
-
-        int status = 0;
-        ORB orb = null;
-        try {
-            orb = ORB.init(args, props);
-            status = run(orb, args);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            status = 1;
-        }
-
-        if (orb != null) {
-            try {
-                orb.destroy();
-            } catch (Exception ex) {
-                ex.printStackTrace();
-                status = 1;
-            }
-        }
-
-        System.exit(status);
-    }
-}
diff --git a/yoko-verify/src/test/java/test/codesets/Server.java b/yoko-verify/src/test/java/test/codesets/Server.java
deleted file mode 100644
index 1c4eba017..000000000
--- a/yoko-verify/src/test/java/test/codesets/Server.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2010 IBM Corporation and others.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an \"AS IS\" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * SPDX-License-Identifier: Apache-2.0
- */
-package test.codesets;
-
-import java.util.Properties;
-import org.omg.CORBA.*;
-import org.omg.PortableServer.*;
-import java.io.*;
-
-final public class Server {
-    public static int run(ORB orb, String[] args)
-            throws org.omg.CORBA.UserException {
-        //
-        // Resolve Root POA
-        //
-        POA poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
-
-        //
-        // Activate the POA manager
-        //
-        POAManager manager = poa.the_POAManager();
-        manager.activate();
-
-        //
-        // Create implementation object
-        //
-        TestCodeSets_impl i = new TestCodeSets_impl(orb);
-        TestCodeSets testCodeSets = i._this(orb);
-
-        //
-        // Save references. This must be done after POA manager activation,
-        // otherwise there is a potential for a race condition between the
-        // client sending request and the server not being ready yet.
-        //
-        String s = orb.object_to_string(testCodeSets);
-
-        String refFile = "TestCodeSets.ref";
-        try {
-            String ref = orb.object_to_string(testCodeSets);
-            FileOutputStream file = new FileOutputStream(refFile);
-            PrintWriter out = new PrintWriter(file);
-            out.println(ref);
-            out.flush();
-            file.close();
-        } catch (IOException ex) {
-            System.err.println("Can't write to `" + ex.getMessage() + "'");
-            return 1;
-        }
-
-        //
-        // Give up control to the ORB
-        //
-        orb.run();
-
-        File file = new File(refFile);
-        file.delete();
-
-        return 0;
-    }
-
-    public static void main(String[] args) {
-        java.util.Properties props = new Properties();
-        props.putAll(System.getProperties());
-        props.put("org.omg.CORBA.ORBClass", "org.apache.yoko.orb.CORBA.ORB");
-        props.put("org.omg.CORBA.ORBSingletonClass",
-                "org.apache.yoko.orb.CORBA.ORBSingleton");
-
-        int status = 0;
-        ORB orb = null;
-
-        try {
-            orb = ORB.init(args, props);
-            status = run(orb, args);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            status = 1;
-        }
-
-        if (orb != null) {
-            try {
-                orb.destroy();
-            } catch (Exception ex) {
-                ex.printStackTrace();
-                status = 1;
-            }
-        }
-
-        System.exit(status);
-    }
-}
diff --git a/yoko-verify/src/test/java/test/codesets/runtest b/yoko-verify/src/test/java/test/codesets/runtest
deleted file mode 100644
index f8736958c..000000000
--- a/yoko-verify/src/test/java/test/codesets/runtest
+++ /dev/null
@@ -1,152 +0,0 @@
-#
-#  Licensed to the Apache Software Foundation (ASF) under one or more
-#  contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-
-#
-# Try to find top-level directory
-#
-if test -f ob/src/com/ooc/CORBA/ORB.java
-then
-    top_srcdir=ob
-elif test -f src/com/ooc/CORBA/ORB.java
-then
-    top_srcdir=.
-elif test -f ../src/com/ooc/CORBA/ORB.java
-then
-    top_srcdir=..
-elif test -f ../../src/com/ooc/CORBA/ORB.java
-then
-    top_srcdir=../..
-elif test -f ../../../src/com/ooc/CORBA/ORB.java
-then
-    top_srcdir=../../..
-elif test -f ../../../../src/com/ooc/CORBA/ORB.java
-then
-    top_srcdir=../../../..
-else
-    $echo "$0: can't find top-level directory"
-    exit
-fi
-
-#
-# Run standard init script
-#
-. $top_srcdir/config/sh.init
-. $top_srcdir/config/testutil.sh
-
-#
-# Set Java CLASSPATH
-#
-CLASSPATH="$top_srcdir/lib${SEPARATOR}$CLASSPATH"
-export CLASSPATH
-
-#
-# Set the "java.endorsed.dirs" property
-#
-set_java_endorsed_dirs
-
-#
-# Delete old log files
-#
-rm -f codeset_client.log
-rm -f codeset_server.log
-
-#
-# Set name of reference file
-#
-ref=TestCodeSets.ref
-
-#
-# Main test function
-#
-runtest()
-{
-$echo
-$echo Client command is \"$client\"
-$echo Server command is \"$server\"
-
-#
-# Start server
-#
-$echo "Waiting for server to start up... \c"
-rm -f $ref
-( $server & echo $! > srvid ) 2>&1 | tee -a codeset_server.log &
-count=0
-while test ! -s $ref -a $count -lt 8
-do
-    sleep 1
-    count=`expr $count + 1`
-done
-if test ! -s $ref
-then
-    $echo "Failed!"
-    $echo "(Server was not started)"
-    exit
-else
-    $echo "Done!"
-fi
-#
-# Start client
-#
-$client 2>&1 | tee -a codeset_client.log
-
-#
-# Wait for server deactivation
-#
-$echo "Waiting for server to deactivate... \c"
-count=0
-while test -r $ref -a $count -lt 3
-do
-    sleep 1
-    count=`expr $count + 1`
-done
-
-if test -r $ref
-then
-    $echo "Failed!"
-    $echo "(Server was not deactivated by client - deactivating server now)"
-    deactivate
-else
-    $echo "Done!"
-fi
-}
-
-#
-# Test with standard code sets
-#
-client="$JAVA test.codesets.Client"
-server="$JAVA test.codesets.Server"
-runtest
-client="$JAVA test.codesets.Client"
-server="$JAVA test.codesets.Server -OAversion 1.1"
-runtest
-
-#
-# Test with other code set for both server and client
-#
-client="$JAVA test.codesets.Client -ORBnative_cs ISO/IEC 8859-5"
-server="$JAVA test.codesets.Server -ORBnative_cs ISO/IEC 8859-5"
-runtest
-client="$JAVA test.codesets.Client -ORBnative_cs ISO/IEC 8859-5"
-server="$JAVA test.codesets.Server -ORBnative_cs ISO/IEC 8859-5 -OAversion 1.1"
-runtest
-client="$JAVA test.codesets.Client -ORBnative_cs ISO 8859-1"
-server="$JAVA test.codesets.Server -ORBnative_cs ISO 8859-4"
-runtest
-client="$JAVA test.codesets.Client -ORBnative_cs ISO 8859-1"
-server="$JAVA test.codesets.Server -ORBnative_cs ISO 8859-4 -OAversion 1.1"
-runtest
-

From 7c92634dbdd5e43a2716c66704d28c8023792f65 Mon Sep 17 00:00:00 2001
From: Joe Chacko 
Date: Fri, 13 Feb 2026 22:40:28 +0000
Subject: [PATCH 16/18] test: add CESU-8 encoding tests for supplementary
 characters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Add test coverage for both UTF-8 and CESU-8 encoding of supplementary
characters (emoji) in UtfStringsTest.

- Add unicodeSupplementaryTestStrings() test data source with emoji
- Separate emoji tests from BMP character tests
- Add writeUtf8/readUtf8 tests for proper UTF-8 encoding (4-byte)
- Add writeCesu8/readCesu8 tests for CESU-8 encoding (two 3-byte)
- Add writeUtf16/readUtf16 tests for UTF-16 encoding
- Use YasfThreadLocal to control WRITE_UTF8_AS_UTF8 flag in tests
- Reformat existing test data for consistency
- Rename test methods for clarity (remove "String"/"Wstring" suffix)
- Move helper method to end of class

Tests verify that emoji characters (waving hand 👋, globe 🌍) are
correctly encoded in both UTF-8 (f09f918b) and CESU-8 (eda0bded b18b).
---
 .../org/apache/yoko/UtfStringsTest.java       | 365 ++++++++++--------
 1 file changed, 208 insertions(+), 157 deletions(-)

diff --git a/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java b/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java
index 980f7d7fb..8eebe22f7 100644
--- a/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java
+++ b/yoko-verify/src/test/java-testify/org/apache/yoko/UtfStringsTest.java
@@ -18,22 +18,26 @@
 package org.apache.yoko;
 
 import org.apache.yoko.io.ReadBuffer;
-import org.apache.yoko.orb.CORBA.YokoInputStream;
 import org.apache.yoko.orb.CORBA.ORB;
+import org.apache.yoko.orb.CORBA.YokoInputStream;
 import org.apache.yoko.orb.CORBA.YokoOutputStream;
 import org.apache.yoko.orb.OB.CodecPair;
 import org.apache.yoko.orb.OB.ORBInstance;
+import org.apache.yoko.util.yasf.YasfThreadLocal;
 import org.junit.jupiter.api.TestInstance;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
+import java.util.EnumSet;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
+import static java.util.EnumSet.complementOf;
 import static org.apache.yoko.orb.OB.CodeSetInfo.UTF_16;
 import static org.apache.yoko.orb.OB.CodeSetInfo.UTF_8;
 import static org.apache.yoko.orb.OCI.GiopVersion.GIOP1_2;
+import static org.apache.yoko.util.yasf.Yasf.WRITE_UTF8_AS_UTF8;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
 import static testify.hex.HexBuilder.buildHex;
@@ -43,183 +47,223 @@
 class UtfStringsTest {
     static Stream unicodeTestStrings() {
         return Stream.of(
-            // Basic ASCII
-            Arguments.of(
-                "Basic ASCII greeting",
-                "Hello, World!",
-                "0000000e 48656c6c 6f2c2057 6f726c64 2100",
-                "0000001a 00480065 006c006c 006f002c 00200057 006f0072 006c0064 0021"
-            ),
-            Arguments.of(
-                "ASCII digits",
-                "0123456789",
-                "0000000b 30313233 34353637 383900",
-                "00000014 00300031 00320033 00340035 00360037 00380039"
-            ),
-            // Latin Extended
-            Arguments.of(
-                "Latin extended characters",
-                "Caf\u00e9 r\u00e9sum\u00e9",
-                "0000000f 436166c3 a92072c3 a973756d c3a900",
-                "00000016 00430061 006600e9 00200072 00e90073 0075006d 00e9"
-            ),
-            Arguments.of(
-                "German umlaut",
-                "Z\u00fcrich",
-                "00000008 5ac3bc72 69636800",
-                "0000000c 005a00fc 00720069 00630068"
-            ),
-            // Cyrillic
-            Arguments.of(
-                "Cyrillic - Privet (Hello)",
-                "\u041f\u0440\u0438\u0432\u0435\u0442",
-                "0000000d d09fd180 d0b8d0b2 d0b5d182 00",
-                "0000000c 041f0440 04380432 04350442"
-            ),
-            // Greek
-            Arguments.of(
-                "Greek - Geia (Hello)",
-                "\u0393\u03b5\u03b9\u03b1",
-                "00000009 ce93ceb5 ceb9ceb1 00",
-                "00000008 039303b5 03b903b1"
-            ),
-            // CJK
-            Arguments.of(
-                "Chinese - Ni hao (Hello)",
-                "\u4f60\u597d",
-                "00000007 e4bda0e5 a5bd00",
-                "00000004 4f60597d"
-            ),
-            Arguments.of(
-                "Japanese - Konnichiwa (Hello)",
-                "\u3053\u3093\u306b\u3061\u306f",
-                "00000010 e38193e3 8293e381 abe381a1 e381af00",
-                "0000000a 30533093 306b3061 306f"
-            ),
-            Arguments.of(
-                "Korean - Annyeong (Hello)",
-                "\uc548\ub155",
-                "00000007 ec9588eb 859500",
-                "00000004 c548b155"
-            ),
-            // Arabic (RTL)
-            Arguments.of(
-                "Arabic RTL - Marhaba (Hello)",
-                "\u0645\u0631\u062d\u0628\u0627",
-                "0000000b d985d8b1 d8add8a8 d8a700",
-                "0000000a 06450631 062d0628 0627"
-            ),
-            // Hebrew (RTL)
-            Arguments.of(
-                "Hebrew RTL - Shalom (Hello)",
-                "\u05e9\u05dc\u05d5\u05dd",
-                "00000009 d7a9d79c d795d79d 00",
-                "00000008 05e905dc 05d505dd"
-            ),
-            // Emoji (surrogate pairs)
-            Arguments.of(
-                "Emoji - waving hand",
-                "\ud83d\udc4b",
-                "00000007 eda0bded b18b00",
-                "00000004 d83ddc4b"
-            ),
-            Arguments.of(
-                "Emoji - globe",
-                "\ud83c\udf0d",
-                "00000007 eda0bced bc8d00",
-                "00000004 d83cdf0d"
-            ),
-            // Mathematical symbols
-            Arguments.of(
-                "Math symbols - sum, infinity, approximately",
-                "\u2211\u221e\u2248",
-                "0000000a e28891e2 889ee289 8800",
-                "00000006 2211221e 2248"
-            ),
-            // Edge cases
-            Arguments.of(
-                "Empty string",
-                "",
-                "00000001 00",
-                "00000000"
-            ),
-            Arguments.of(
-                "First non-ASCII character",
-                "\u0080",
-                "00000003 c28000",
-                "00000002 0080"
-            ),
-            Arguments.of(
-                "Last BMP character",
-                "\uffff",
-                "00000004 efbfbf00",
-                "00000002 ffff"
-            ),
-            // Mixed content
-            Arguments.of(
-                "Mixed - Euro symbol",
-                "Price: \u20ac50",
-                "0000000d 50726963 653a20e2 82ac3530 00",
-                "00000014 00500072 00690063 0065003a 002020ac 00350030"
-            ),
-            Arguments.of(
-                "Mixed - degree symbol",
-                "Temp: 25\u00b0C",
-                "0000000c 54656d70 3a203235 c2b04300",
-                "00000014 00540065 006d0070 003a0020 00320035 00b00043"
-            ),
-            // Normalization test
-            Arguments.of(
-                "Normalization - precomposed e-acute",
-                "caf\u00e9",
-                "00000006 636166c3 a900",
-                "00000008 00630061 006600e9"
-            ),
-            Arguments.of(
-                "Normalization - e + combining acute",
-                "cafe\u0301",
-                "00000007 63616665 cc8100",
-                "0000000a 00630061 00660065 0301"
-            ),
-            // Zero-width
-            Arguments.of(
-                "Zero-width space",
-                "Hello\u200bWorld",
-                "0000000e 48656c6c 6fe2808b 576f726c 6400",
-                "00000016 00480065 006c006c 006f200b 0057006f 0072006c 0064"
-            )
+                // Basic ASCII
+                Arguments.of(
+                        "Basic ASCII greeting",
+                        "Hello, World!",
+                        "0000000e 48656c6c 6f2c2057 6f726c64 2100",
+                        "0000001a 00480065 006c006c 006f002c 00200057 006f0072 006c0064 0021"
+                ),
+                Arguments.of(
+                        "ASCII digits",
+                        "0123456789",
+                        "0000000b 30313233 34353637 383900",
+                        "00000014 00300031 00320033 00340035 00360037 00380039"
+                ),
+                // Latin Extended
+                Arguments.of(
+                        "Latin extended characters",
+                        "Caf\u00e9 r\u00e9sum\u00e9",
+                        "0000000f 436166c3 a92072c3 a973756d c3a900",
+                        "00000016 00430061 006600e9 00200072 00e90073 0075006d 00e9"
+                ),
+                Arguments.of(
+                        "German umlaut",
+                        "Z\u00fcrich",
+                        "00000008 5ac3bc72 69636800",
+                        "0000000c 005a00fc 00720069 00630068"
+                ),
+                // Cyrillic
+                Arguments.of(
+                        "Cyrillic - Privet (Hello)",
+                        "\u041f\u0440\u0438\u0432\u0435\u0442",
+                        "0000000d d09fd180 d0b8d0b2 d0b5d182 00",
+                        "0000000c 041f0440 04380432 04350442"
+                ),
+                // Greek
+                Arguments.of(
+                        "Greek - Geia (Hello)",
+                        "\u0393\u03b5\u03b9\u03b1",
+                        "00000009 ce93ceb5 ceb9ceb1 00",
+                        "00000008 039303b5 03b903b1"
+                ),
+                // CJK
+                Arguments.of(
+                        "Chinese - Ni hao (Hello)",
+                        "\u4f60\u597d",
+                        "00000007 e4bda0e5 a5bd00",
+                        "00000004 4f60597d"
+                ),
+                Arguments.of(
+                        "Japanese - Konnichiwa (Hello)",
+                        "\u3053\u3093\u306b\u3061\u306f",
+                        "00000010 e38193e3 8293e381 abe381a1 e381af00",
+                        "0000000a 30533093 306b3061 306f"
+                ),
+                Arguments.of(
+                        "Korean - Annyeong (Hello)",
+                        "\uc548\ub155",
+                        "00000007 ec9588eb 859500",
+                        "00000004 c548b155"
+                ),
+                // Arabic (RTL)
+                Arguments.of(
+                        "Arabic RTL - Marhaba (Hello)",
+                        "\u0645\u0631\u062d\u0628\u0627",
+                        "0000000b d985d8b1 d8add8a8 d8a700",
+                        "0000000a 06450631 062d0628 0627"
+                ),
+                // Hebrew (RTL)
+                Arguments.of(
+                        "Hebrew RTL - Shalom (Hello)",
+                        "\u05e9\u05dc\u05d5\u05dd",
+                        "00000009 d7a9d79c d795d79d 00",
+                        "00000008 05e905dc 05d505dd"
+                ),
+                // Mathematical symbols
+                Arguments.of(
+                        "Math symbols - sum, infinity, approximately",
+                        "\u2211\u221e\u2248",
+                        "0000000a e28891e2 889ee289 8800",
+                        "00000006 2211221e 2248"
+                ),
+                // Edge cases
+                Arguments.of(
+                        "Empty string",
+                        "",
+                        "00000001 00",
+                        "00000000"
+                ),
+                Arguments.of(
+                        "First non-ASCII character",
+                        "\u0080",
+                        "00000003 c28000",
+                        "00000002 0080"
+                ),
+                Arguments.of(
+                        "Last BMP character",
+                        "\uffff",
+                        "00000004 efbfbf00",
+                        "00000002 ffff"
+                ),
+                // Mixed content
+                Arguments.of(
+                        "Mixed - Euro symbol",
+                        "Price: \u20ac50",
+                        "0000000d 50726963 653a20e2 82ac3530 00",
+                        "00000014 00500072 00690063 0065003a 002020ac 00350030"
+                ),
+                Arguments.of(
+                        "Mixed - degree symbol",
+                        "Temp: 25\u00b0C",
+                        "0000000c 54656d70 3a203235 c2b04300",
+                        "00000014 00540065 006d0070 003a0020 00320035 00b00043"
+                ),
+                // Normalization test
+                Arguments.of(
+                        "Normalization - precomposed e-acute",
+                        "caf\u00e9",
+                        "00000006 636166c3 a900",
+                        "00000008 00630061 006600e9"
+                ),
+                Arguments.of(
+                        "Normalization - e + combining acute",
+                        "cafe\u0301",
+                        "00000007 63616665 cc8100",
+                        "0000000a 00630061 00660065 0301"
+                ),
+                // Zero-width
+                Arguments.of(
+                        "Zero-width space",
+                        "Hello\u200bWorld",
+                        "0000000e 48656c6c 6fe2808b 576f726c 6400",
+                        "00000016 00480065 006c006c 006f200b 0057006f 0072006c 0064"
+                )
         );
     }
 
-    static YokoOutputStream newUtfSpecificOutputStream() {
-        ORB orb = (ORB) ORB.init((String[]) null, null);
-        ORBInstance orbInst = orb._OB_ORBInstance();
-        CodecPair codecs = CodecPair.create(UTF_8.id, UTF_16.id);
-        return new YokoOutputStream(codecs, GIOP1_2);
-    }
-
     @ParameterizedTest(name = "{0}")
     @MethodSource("unicodeTestStrings")
-    void writeUtf8String(String description, String text, String utf8Hex, String utf16Hex) {
+    void writeUtf8(String description, String text, String utf8Hex, String utf16Hex) {
         checkWrittenForm(o -> o.write_string(text), utf8Hex);
     }
 
     @ParameterizedTest(name = "{0}")
     @MethodSource("unicodeTestStrings")
-    void readUtf8String(String description, String expectedText, String utf8Hex, String utf16Hex) {
+    void readUtf8(String description, String expectedText, String utf8Hex, String utf16Hex) {
         String actualText = writeHex(utf8Hex).read_string();
         assertEquals(expectedText, actualText);
     }
 
     @ParameterizedTest(name = "{0}")
     @MethodSource("unicodeTestStrings")
-    void writeUtf16Wstring(String description, String text, String utf8Hex, String utf16Hex) {
+    void writeUtf16(String description, String text, String utf8Hex, String utf16Hex) {
         checkWrittenForm(o -> o.write_wstring(text), utf16Hex);
     }
 
     @ParameterizedTest(name = "{0}")
     @MethodSource("unicodeTestStrings")
-    void readUtf16String(String description, String expectedText, String utf8Hex, String utf16Hex) {
+    void readUtf16(String description, String expectedText, String utf8Hex, String utf16Hex) {
+        String actualText = writeHex(utf16Hex).read_wstring();
+        assertEquals(expectedText, actualText);
+    }
+
+    static Stream unicodeSupplementaryTestStrings() {
+        return Stream.of(
+                // Emoji (surrogate pairs)
+                Arguments.of(
+                        "Emoji - waving hand",
+                        "\ud83d\udc4b",
+                        "00000005 f09f918b 00",
+                        "00000007 eda0bded b18b00",
+                        "00000004 d83ddc4b"
+                ),
+                Arguments.of(
+                        "Emoji - globe",
+                        "\ud83c\udf0d",
+                        "00000005 f09f8c8d 00",
+                        "00000007 eda0bced bc8d00",
+                        "00000004 d83cdf0d"
+                ));
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("unicodeSupplementaryTestStrings")
+    void writeUtf8(String description, String text, String utf8Hex, String cesu8Hex, String utf16Hex) {
+        checkWrittenForm(o -> o.write_string(text), utf8Hex);
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("unicodeSupplementaryTestStrings")
+    void readUtf8(String description, String expectedText, String utf8Hex, String cesu8Hex, String utf16Hex) {
+        String actualText = writeHex(utf8Hex).read_string();
+        assertEquals(expectedText, actualText);
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("unicodeSupplementaryTestStrings")
+    void writeCesu8(String description, String text, String utf8Hex, String cesu8Hex, String utf16Hex) {
+        YasfThreadLocal.push(complementOf(EnumSet.of(WRITE_UTF8_AS_UTF8)));
+        try { checkWrittenForm(o -> o.write_string(text), cesu8Hex); }
+        finally { YasfThreadLocal.pop(); }
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("unicodeSupplementaryTestStrings")
+    void readCesu8(String description, String expectedText, String utf8Hex, String cesu8Hex, String utf16Hex) {
+        String actualText = writeHex(cesu8Hex).read_string();
+        assertEquals(expectedText, actualText);
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("unicodeSupplementaryTestStrings")
+    void writeUtf16(String description, String text, String utf8Hex, String cesu8Hex, String utf16Hex) {
+        checkWrittenForm(o -> o.write_wstring(text), utf16Hex);
+    }
+
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("unicodeSupplementaryTestStrings")
+    void readUtf16(String description, String expectedText, String utf8Hex, String cesu8Hex, String utf16Hex) {
         String actualText = writeHex(utf16Hex).read_wstring();
         assertEquals(expectedText, actualText);
     }
@@ -248,4 +292,11 @@ static void checkWrittenForm(Consumer writeTextTo, String expe
             assertEquals(expectedHex, actualHex);
         }
     }
+
+    static YokoOutputStream newUtfSpecificOutputStream() {
+        ORB orb = (ORB) ORB.init((String[]) null, null);
+        ORBInstance orbInst = orb._OB_ORBInstance();
+        CodecPair codecs = CodecPair.create(UTF_8.id, UTF_16.id);
+        return new YokoOutputStream(codecs, GIOP1_2);
+    }
 }

From 57fc9456ccbb622a43b7555f2d38ca2185f4cac1 Mon Sep 17 00:00:00 2001
From: Joe Chacko 
Date: Sun, 15 Feb 2026 18:10:33 +0000
Subject: [PATCH 17/18] fix: use CESU-8 encoding with older Yoko

Add WRITE_UTF8_AS_UTF8 flag to Yasf enum to enable proper UTF-8 encoding
of surrogate pairs when communicating with newer Yoko versions.

Changes:
- Add WRITE_UTF8_AS_UTF8(2) to Yasf enum for stream format negotiation
- Modify Utf8Codec.writeChar() to conditionally handle surrogate pairs
  based on YASF flag support
- When flag is supported, properly validate and combine surrogate pairs
  into full codepoints before encoding
- When flag is not supported (older Yoko), fall back to CESU-8 behavior
  by encoding surrogates as individual 3-byte UTF-8 sequences

This change maintains backward compatibility with older Yoko versions
while enabling correct UTF-8 encoding for supplementary characters
(codepoints > U+FFFF) when both endpoints support the new flag.

Modified files:
- yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java
- yoko-util/src/main/java/org/apache/yoko/util/yasf/Yasf.java
---
 .../org/apache/yoko/codecs/Utf8Codec.java     | 37 ++++++++++---------
 .../java/org/apache/yoko/util/yasf/Yasf.java  |  1 +
 2 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java
index 5135b9a61..c32c2443a 100644
--- a/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java
+++ b/yoko-core/src/main/java/org/apache/yoko/codecs/Utf8Codec.java
@@ -20,6 +20,7 @@
 import org.apache.yoko.io.ReadBuffer;
 import org.apache.yoko.io.WriteBuffer;
 import org.apache.yoko.orb.OB.CodeSetInfo;
+import org.apache.yoko.util.yasf.Yasf;
 import org.omg.CORBA.DATA_CONVERSION;
 
 import static java.lang.Character.highSurrogate;
@@ -33,6 +34,7 @@
 import static org.apache.yoko.codecs.Util.ASCII_REPLACEMENT_BYTE;
 import static org.apache.yoko.codecs.Util.UNICODE_REPLACEMENT_CHAR;
 import static org.apache.yoko.util.MinorCodes.MinorUTF8Encoding;
+import static org.apache.yoko.util.yasf.Yasf.WRITE_UTF8_AS_UTF8;
 import static org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE;
 
 final class Utf8Codec implements CharCodec {
@@ -135,30 +137,31 @@ public int octetCount(char c) {
     public void writeChar(char c, WriteBuffer out) {
         try {
             final int codepoint;
-            if (0 != highSurrogate) {
-                try {
-                    if (isHighSurrogate(c)) throw new InternalException(String.format("Received two high surrogates in a row: 0x%04X 0x%04X", highSurrogate, c));
-                    if (!isLowSurrogate(c)) throw new InternalException(String.format("Expected low surrogate but received: 0x%04X", (int) c));
-                    codepoint = toCodePoint(highSurrogate, c);
-                    // undo the replacement byte written out when the high surrogate was received
-                    out.rewind(1);
-                } finally {
-                    highSurrogate = 0;
-                }
-            } else {
-                if (isHighSurrogate(c)) {
+            // if writing CESU-8 (i.e. talking to an older Yoko)
+            // then simply marshal surrogate codepoints as 3-byte UTF-8 sequences
+            // and therefore pass them straight through without any checking
+            if (WRITE_UTF8_AS_UTF8.isSupported()) {
+                if (0 != highSurrogate) {
+                    try {
+                        if (isHighSurrogate(c)) throw new InternalException(String.format("Received two high surrogates in a row: 0x%04X 0x%04X", (int) highSurrogate, (int) c));
+                        if (!isLowSurrogate(c)) throw new InternalException(String.format("Expected low surrogate but received: 0x%04X", (int) c));
+                        codepoint = toCodePoint(highSurrogate, c);
+                        // undo the replacement byte written out when the high surrogate was received
+                        out.rewind(1);
+                    } finally {
+                        highSurrogate = 0;
+                    }
+                } else if (isHighSurrogate(c)) {
                     highSurrogate = c;
                     // write a '?' in case we never get the low surrogate
                     out.writeByte(ASCII_REPLACEMENT_BYTE);
                     return;
-                }
-                if (isLowSurrogate(c)) {
+                } else if (isLowSurrogate(c)) {
                     DATA_OUT_LOG.warning(String.format("Received unexpected low surrogate: 0x%04X", (int) c));
                     out.writeByte(ASCII_REPLACEMENT_BYTE);
                     return;
-                }
-                codepoint = c;
-            }
+                } else codepoint = c;
+            } else codepoint = c;
             writeBytes(codepoint, out);
         } catch (InternalException x) {
             DATA_OUT_LOG.warning(x.getMessage());
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/yasf/Yasf.java b/yoko-util/src/main/java/org/apache/yoko/util/yasf/Yasf.java
index a5c5a1370..ad59091ce 100644
--- a/yoko-util/src/main/java/org/apache/yoko/util/yasf/Yasf.java
+++ b/yoko-util/src/main/java/org/apache/yoko/util/yasf/Yasf.java
@@ -38,6 +38,7 @@
 public enum Yasf {
     ENUM_FIXED(0),
     NON_SERIALIZABLE_FIELD_IS_ABSTRACT_VALUE(1),
+    WRITE_UTF8_AS_UTF8(2),
     ;
     // TODO - Get the OMG to assign this value to Yoko
     public static final int TAG_YOKO_AUXILIARY_STREAM_FORMAT = 0xeeeeeeee;

From f6d66c560ea4bc3ba4aa6eb81210fdc86a5ac612 Mon Sep 17 00:00:00 2001
From: Joe Chacko 
Date: Mon, 23 Feb 2026 22:51:33 +0000
Subject: [PATCH 18/18] refactor(test): add file sync to test servers

- Add file.getFD().sync() calls after writing IOR files to ensure data is flushed to disk
- Apply to Server classes in ORBTest, iiopplugin, local, pi, poa, retry, and tnaming test packages
- Add missing imports (FileOutputStream, PrintWriter) where needed
- Remove fully qualified class names in favor of imports
- Simplify policy array initialization using array initializer syntax
- Remove unnecessary comments and empty statements
- Consolidate multi-line statements for better readability
- Add static import for ParseArgs in TestMultipleOrbsThreadedServer
- Replace FileWriter with FileOutputStream in pi.Server and tnaming.Server for consistency
---
 yoko-verify/src/test/java/ORBTest/Server.java | 13 ++--
 .../src/test/java/test/iiopplugin/Server.java |  6 +-
 .../src/test/java/test/local/Server.java      | 10 ++-
 yoko-verify/src/test/java/test/pi/Server.java |  9 ++-
 .../java/test/poa/TestMultipleOrbsServer.java | 22 ++----
 .../poa/TestMultipleOrbsThreadedServer.java   | 34 +++------
 .../src/test/java/test/retry/Server.java      | 73 ++++++++-----------
 .../src/test/java/test/tnaming/Server.java    |  7 +-
 8 files changed, 77 insertions(+), 97 deletions(-)

diff --git a/yoko-verify/src/test/java/ORBTest/Server.java b/yoko-verify/src/test/java/ORBTest/Server.java
index 553b218a4..b65e7201a 100644
--- a/yoko-verify/src/test/java/ORBTest/Server.java
+++ b/yoko-verify/src/test/java/ORBTest/Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
  */
 package ORBTest;
 
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
 import java.util.Properties;
 import org.omg.CORBA.*;
 import org.omg.PortableServer.*;
@@ -24,8 +26,7 @@
 public class Server {
     private static final String refFile = "TestIntf.ref";
 
-    public static int run(ORB orb, boolean nonBlocking, String[] args)
-            throws org.omg.CORBA.UserException {
+    public static int run(ORB orb, boolean nonBlocking, String[] args) throws UserException {
         //
         // Resolve Root POA
         //
@@ -51,11 +52,11 @@ public static int run(ORB orb, boolean nonBlocking, String[] args)
         // not being ready yet.
         //
         try {
-            java.io.FileOutputStream file = new java.io.FileOutputStream(
-                    refFile);
-            java.io.PrintWriter out = new java.io.PrintWriter(file);
+            FileOutputStream file = new FileOutputStream(refFile);
+            PrintWriter out = new PrintWriter(file);
             out.println(impl);
             out.flush();
+            file.getFD().sync();
             file.close();
         } catch (java.io.IOException ex) {
             System.err.println("Can't write to `" + ex.getMessage() + "'");
diff --git a/yoko-verify/src/test/java/test/iiopplugin/Server.java b/yoko-verify/src/test/java/test/iiopplugin/Server.java
index 47cbe5837..cb3792a5b 100644
--- a/yoko-verify/src/test/java/test/iiopplugin/Server.java
+++ b/yoko-verify/src/test/java/test/iiopplugin/Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -49,11 +49,11 @@ private static int run(ORB orb) throws UserException {
         String refFile = "Test.ref";
         try {
             String ref = orb.object_to_string(test);
-            FileOutputStream file = new FileOutputStream(
-                    refFile);
+            FileOutputStream file = new FileOutputStream(refFile);
             PrintWriter out = new PrintWriter(file);
             out.println(ref);
             out.flush();
+            file.getFD().sync();
             file.close();
         } catch (IOException ex) {
             System.err.println("Can't write to `" + ex.getMessage() + "'");
diff --git a/yoko-verify/src/test/java/test/local/Server.java b/yoko-verify/src/test/java/test/local/Server.java
index cc61a645b..5c3e5e717 100644
--- a/yoko-verify/src/test/java/test/local/Server.java
+++ b/yoko-verify/src/test/java/test/local/Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
  */
 package test.local;
 
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
 import java.util.Properties;
 import org.omg.CORBA.*;
 import org.omg.PortableServer.*;
@@ -50,11 +52,11 @@ public static int run(ORB orb, String[] args)
         String refFile = "Test.ref";
         try {
             String ref = orb.object_to_string(test);
-            java.io.FileOutputStream file = new java.io.FileOutputStream(
-                    refFile);
-            java.io.PrintWriter out = new java.io.PrintWriter(file);
+            FileOutputStream file = new FileOutputStream(refFile);
+            PrintWriter out = new PrintWriter(file);
             out.println(ref);
             out.flush();
+            file.getFD().sync();
             file.close();
         } catch (java.io.IOException ex) {
             System.err.println("Can't write to `" + ex.getMessage() + "'");
diff --git a/yoko-verify/src/test/java/test/pi/Server.java b/yoko-verify/src/test/java/test/pi/Server.java
index 298533ed8..f3f9f0dc8 100644
--- a/yoko-verify/src/test/java/test/pi/Server.java
+++ b/yoko-verify/src/test/java/test/pi/Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,11 +44,11 @@
 import org.omg.PortableServer.ServantRetentionPolicyValueHelper;
 
 import java.io.File;
-import java.io.FileWriter;
+import java.io.FileOutputStream;
 import java.io.PrintWriter;
 import java.util.Properties;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertTrue;
 
 public final class Server {
     private static String refFile = "TestInterface.ref";
@@ -60,7 +60,7 @@ static void ServerRegisterInterceptors(Properties props) {
     }
 
     static void ServerRun(ORB orb, boolean nonBlocking, String[] args) throws Exception {
-        try (PrintWriter out = new PrintWriter(new FileWriter(refFile))) {
+        try (FileOutputStream file = new FileOutputStream(refFile); PrintWriter out = new PrintWriter(file)) {
             try {
                 Object c = Class.forName("test.pi.ServerORBInitializer_impl");
                 System.out.println("Got class " + c);
@@ -132,6 +132,7 @@ static void ServerRun(ORB orb, boolean nonBlocking, String[] args) throws Except
                 writeRef(orb, out, objImpl);
                 writeRef(orb, out, objDSIImpl);
                 out.flush();
+                file.getFD().sync();
                 System.out.println("Wrote refs");
 
                 
diff --git a/yoko-verify/src/test/java/test/poa/TestMultipleOrbsServer.java b/yoko-verify/src/test/java/test/poa/TestMultipleOrbsServer.java
index 0e31d3c65..74e3ed8d8 100644
--- a/yoko-verify/src/test/java/test/poa/TestMultipleOrbsServer.java
+++ b/yoko-verify/src/test/java/test/poa/TestMultipleOrbsServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@
 final public class TestMultipleOrbsServer {
 
     public static void main(String[] args) {
-        java.util.Properties props = new Properties();
+        Properties props = new Properties();
         props.putAll(System.getProperties());
         props.put("org.omg.CORBA.ORBClass", "org.apache.yoko.orb.CORBA.ORB");
         props.put("org.omg.CORBA.ORBSingletonClass",
@@ -42,28 +42,21 @@ public static void main(String[] args) {
             //
             // Resolve Root POA and POA Manager
             //
-            org.omg.CORBA.Object poaObj = orb1
-                    .resolve_initial_references("RootPOA");
-            org.omg.PortableServer.POA rootPOA1 = org.omg.PortableServer.POAHelper
-                    .narrow(poaObj);
-            org.omg.PortableServer.POAManager manager1 = rootPOA1
-                    .the_POAManager();
+            org.omg.CORBA.Object poaObj = orb1.resolve_initial_references("RootPOA");
+            org.omg.PortableServer.POA rootPOA1 = org.omg.PortableServer.POAHelper.narrow(poaObj);
+            org.omg.PortableServer.POAManager manager1 = rootPOA1.the_POAManager();
 
             poaObj = orb2.resolve_initial_references("RootPOA");
-            org.omg.PortableServer.POA rootPOA2 = org.omg.PortableServer.POAHelper
-                    .narrow(poaObj);
-            org.omg.PortableServer.POAManager manager2 = rootPOA2
-                    .the_POAManager();
+            org.omg.PortableServer.POA rootPOA2 = org.omg.PortableServer.POAHelper.narrow(poaObj);
+            org.omg.PortableServer.POAManager manager2 = rootPOA2.the_POAManager();
 
             //
             // Create test implementation object in each ORB
             //
             Test_impl testImpl1 = new Test_impl(orb1, rootPOA1);
-            ;
             Test test1 = testImpl1._this(orb1);
 
             Test_impl testImpl2 = new Test_impl(orb2, rootPOA2);
-            ;
             Test test2 = testImpl2._this(orb2);
 
             //
@@ -91,6 +84,7 @@ public static void main(String[] args) {
                 out.println(orb1.object_to_string(server1));
                 out.println(orb2.object_to_string(server2));
                 out.flush();
+                file.getFD().sync();
                 file.close();
             } catch (IOException ex) {
                 System.err.println("Can't write to `" + ex.getMessage() + "'");
diff --git a/yoko-verify/src/test/java/test/poa/TestMultipleOrbsThreadedServer.java b/yoko-verify/src/test/java/test/poa/TestMultipleOrbsThreadedServer.java
index 3a01c40a0..f748ad6ac 100644
--- a/yoko-verify/src/test/java/test/poa/TestMultipleOrbsThreadedServer.java
+++ b/yoko-verify/src/test/java/test/poa/TestMultipleOrbsThreadedServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +20,8 @@
 import java.io.*;
 import java.util.Properties;
 
+import static org.apache.yoko.orb.OBCORBA.ORB_impl.ParseArgs;
+
 final public class TestMultipleOrbsThreadedServer {
     //
     // Define the number of ORB instances to run in separate threads.
@@ -65,18 +67,15 @@ static final class OrbTestThread extends Thread {
             props
                     .put("org.omg.CORBA.ORBClass",
                             "org.apache.yoko.orb.CORBA.ORB");
-            props.put("org.omg.CORBA.ORBSingletonClass",
-                    "org.apache.yoko.orb.CORBA.ORBSingleton");
+            props.put("org.omg.CORBA.ORBSingletonClass", "org.apache.yoko.orb.CORBA.ORBSingleton");
             props.put("yoko.orb.id", orb_id); // Use ORB ID passed
 
             try {
                 String[] args = new String[0];
                 orb_ = org.omg.CORBA.ORB.init(args, props);
 
-                org.omg.CORBA.Object obj = orb_
-                        .resolve_initial_references("RootPOA");
-                org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper
-                        .narrow(obj);
+                org.omg.CORBA.Object obj = orb_.resolve_initial_references("RootPOA");
+                org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow(obj);
                 manager_ = rootPOA.the_POAManager();
 
                 test_ = new TestOrb_impl(orb_);
@@ -122,31 +121,21 @@ public static void main(String[] args) {
         java.util.Properties props = new Properties();
         props.putAll(System.getProperties());
         props.put("org.omg.CORBA.ORBClass", "org.apache.yoko.orb.CORBA.ORB");
-        props.put("org.omg.CORBA.ORBSingletonClass",
-                "org.apache.yoko.orb.CORBA.ORBSingleton");
+        props.put("org.omg.CORBA.ORBSingletonClass", "org.apache.yoko.orb.CORBA.ORBSingleton");
         props.put("yoko.orb.id", ""); // Use default ORB
 
         org.omg.CORBA.ORB orb = null;
 
         try {
-            args = org.apache.yoko.orb.CORBA.ORB.ParseArgs(args, props, null);
+            args = ParseArgs(args, props, null);
             props.put("yoko.orb.conc_model", "threaded");
             props.put("yoko.orb.oa.conc_model", "threaded");
 
-            //
-            // Create ORB
-            //
             orb = org.omg.CORBA.ORB.init(args, props);
 
-            //
-            // Resolve Root POA and POA Manager
-            //
-            org.omg.CORBA.Object poaObj = orb
-                    .resolve_initial_references("RootPOA");
-            org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper
-                    .narrow(poaObj);
-            org.omg.PortableServer.POAManager manager = rootPOA
-                    .the_POAManager();
+            org.omg.CORBA.Object poaObj = orb.resolve_initial_references("RootPOA");
+            org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper.narrow(poaObj);
+            org.omg.PortableServer.POAManager manager = rootPOA.the_POAManager();
 
             //
             // Create threads to run other orb instances
@@ -182,6 +171,7 @@ public static void main(String[] args) {
                 PrintWriter out = new PrintWriter(file);
                 out.println(orb.object_to_string(server));
                 out.flush();
+                file.getFD().sync();
                 file.close();
             } catch (IOException ex) {
                 System.err.println("Can't write to `" + ex.getMessage() + "'");
diff --git a/yoko-verify/src/test/java/test/retry/Server.java b/yoko-verify/src/test/java/test/retry/Server.java
index 7bf49147b..18f558f00 100644
--- a/yoko-verify/src/test/java/test/retry/Server.java
+++ b/yoko-verify/src/test/java/test/retry/Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,8 +17,20 @@
  */
 package test.retry;
 
+import org.omg.CORBA.UserException;
+import org.omg.PortableServer.POA;
+import org.omg.PortableServer.POAHelper;
+import org.omg.PortableServer.POAManager;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
 import java.util.Properties;
 
+import static org.omg.PortableServer.ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION;
+import static org.omg.PortableServer.RequestProcessingPolicyValue.USE_SERVANT_MANAGER;
+import static org.omg.PortableServer.ServantRetentionPolicyValue.NON_RETAIN;
+
 class FwdLocator_impl extends org.omg.CORBA.LocalObject implements
         org.omg.PortableServer.ServantLocator {
     private org.omg.CORBA.Object obj_;
@@ -28,59 +40,42 @@ public FwdLocator_impl(org.omg.CORBA.Object obj) {
     }
 
     public org.omg.PortableServer.Servant preinvoke(byte[] oid,
-            org.omg.PortableServer.POA poa, String operation,
+            POA poa, String operation,
             org.omg.PortableServer.ServantLocatorPackage.CookieHolder cookie)
             throws org.omg.PortableServer.ForwardRequest {
         throw new org.omg.PortableServer.ForwardRequest(obj_);
     }
 
-    public void postinvoke(byte[] oid, org.omg.PortableServer.POA poa,
+    public void postinvoke(byte[] oid, POA poa,
             String operation, java.lang.Object cookie,
             org.omg.PortableServer.Servant servant) {
     }
 }
 
 public class Server {
-    public static int run(org.omg.CORBA.ORB orb, String[] args)
-            throws org.omg.CORBA.UserException {
-        //
-        // Resolve Root POA
-        //
-        org.omg.PortableServer.POA rootPOA = org.omg.PortableServer.POAHelper
-                .narrow(orb.resolve_initial_references("RootPOA"));
+    public static int run(org.omg.CORBA.ORB orb, String[] args) throws UserException {
+        POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
 
-        //
-        // Get a reference to the POA manager and activate it
-        //
-        org.omg.PortableServer.POAManager manager = rootPOA.the_POAManager();
-        manager.activate();
+        rootPOA.the_POAManager().activate();
 
-        org.omg.CORBA.Policy[] policies = new org.omg.CORBA.Policy[3];
-        policies[0] = rootPOA
-                .create_request_processing_policy(org.omg.PortableServer.RequestProcessingPolicyValue.USE_SERVANT_MANAGER);
-        policies[1] = rootPOA
-                .create_servant_retention_policy(org.omg.PortableServer.ServantRetentionPolicyValue.NON_RETAIN);
-        policies[2] = rootPOA
-                .create_implicit_activation_policy(org.omg.PortableServer.ImplicitActivationPolicyValue.NO_IMPLICIT_ACTIVATION);
+        org.omg.CORBA.Policy[] policies = {
+                rootPOA.create_request_processing_policy(USE_SERVANT_MANAGER),
+                rootPOA.create_servant_retention_policy(NON_RETAIN),
+                rootPOA.create_implicit_activation_policy(NO_IMPLICIT_ACTIVATION),
+        };
 
-        //
         // Create two POAs with servant locators, each with its own
         // POAManager (and therefore, each with unique endpoints).
         // The locators will simply raise ForwardRequest for the
         // given object, thus creating an infinite loop.
-        //
-        org.omg.PortableServer.POA poa1 = rootPOA.create_POA("poa1", null,
-                policies);
-        org.omg.PortableServer.POA poa2 = rootPOA.create_POA("poa2", null,
-                policies);
+        POA poa1 = rootPOA.create_POA("poa1", null, policies);
+        POA poa2 = rootPOA.create_POA("poa2", null, policies);
 
         org.omg.CORBA.Object obj1 = poa1.create_reference("IDL:Test:1.0");
         org.omg.CORBA.Object obj2 = poa2.create_reference("IDL:Test:1.0");
 
-        org.omg.PortableServer.ServantLocator locator1 = new FwdLocator_impl(
-                obj2);
-        org.omg.PortableServer.ServantLocator locator2 = new FwdLocator_impl(
-                obj1);
+        org.omg.PortableServer.ServantLocator locator1 = new FwdLocator_impl(obj2);
+        org.omg.PortableServer.ServantLocator locator2 = new FwdLocator_impl(obj1);
 
         poa1.set_servant_manager(locator1);
         poa2.set_servant_manager(locator2);
@@ -93,30 +88,26 @@ public static int run(org.omg.CORBA.ORB orb, String[] args)
         RetryServer_impl serverImpl = new RetryServer_impl(rootPOA, test, retry);
         RetryServer server = serverImpl._this(orb);
 
-        //
         // Save reference. This must be done after POA manager
         // activation, otherwise there is a potential for a race
         // condition between the client sending a request and the
         // server not being ready yet.
-        //
         String refFile = "Test.ref";
         try {
             String ref = orb.object_to_string(server);
-            java.io.FileOutputStream file = new java.io.FileOutputStream(
-                    refFile);
-            java.io.PrintWriter out = new java.io.PrintWriter(file);
+            FileOutputStream file = new FileOutputStream(refFile);
+            PrintWriter out = new PrintWriter(file);
             out.println(ref);
             out.flush();
+            file.getFD().sync();
             file.close();
-        } catch (java.io.IOException ex) {
+        } catch (IOException ex) {
             System.err.println("Can't write to `" + ex.getMessage() + "'");
             return 1;
         }
 
-        //
         // Run implementation
-        //
-        org.omg.PortableServer.POAManager mgr = poa1.the_POAManager();
+        POAManager mgr = poa1.the_POAManager();
         mgr.activate();
         mgr = poa2.the_POAManager();
         mgr.activate();
diff --git a/yoko-verify/src/test/java/test/tnaming/Server.java b/yoko-verify/src/test/java/test/tnaming/Server.java
index dc1b5330d..55cd7a9bb 100644
--- a/yoko-verify/src/test/java/test/tnaming/Server.java
+++ b/yoko-verify/src/test/java/test/tnaming/Server.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 IBM Corporation and others.
+ * Copyright 2026 IBM Corporation and others.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
  */
 package test.tnaming;
 
+import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.PrintWriter;
 import java.nio.file.Files;
@@ -100,7 +101,7 @@ void run() throws Exception {
 
         // use a temporary file to avoid the client picking up an empty file when debugging the server
         Path tmp = Files.createTempFile(refFile, "");
-        try (PrintWriter out = new PrintWriter(new FileWriter(tmp.toFile()))) {
+        try (FileOutputStream file = new FileOutputStream(tmp.toFile()); PrintWriter out = new PrintWriter(file)) {
             System.out.println("server opened file for writing");
             try {
                 NamingContext nc1 = rootNamingContext.new_context();
@@ -113,7 +114,6 @@ void run() throws Exception {
                 NamingContext nc2 = rootNamingContext.bind_new_context(new NameComponent[]{LEVEL1, LEVEL2});
 
                 Util.assertNameNotBound(rootNamingContext, TEST1);
-
                 Util.assertNameNotBound(rootNamingContext, TEST1);
 
                 rootNamingContext.bind(new NameComponent[]{TEST1}, test1);
@@ -156,6 +156,7 @@ void run() throws Exception {
             RefFiles.writeRef(orb, out, test2, rootNamingContext, new NameComponent[]{LEVEL1, TEST2});
             RefFiles.writeRef(orb, out, test3, rootNamingContext, new NameComponent[]{LEVEL1, LEVEL2, TEST3});
             out.flush();
+            file.getFD().sync();
             System.out.println("IORs written to file");
         } catch (java.io.IOException ex) {
             System.err.println("Can't write to `" + ex.getMessage() + "'");