From 8af808ca64779bf722e196fa04e29a4180bad845 Mon Sep 17 00:00:00 2001 From: Zach Bray Date: Wed, 27 Nov 2024 13:07:37 +0000 Subject: [PATCH] [Java] Preserve byte order throughout IR transformations. Previously, the IrDecoder looked at the message header's BEGIN_COMPOSITE token to determine byte order; however, IrEncoder does not write the schema's byte order on tokens like these. Now, the IrDecoder finds the first real ENCODING token and reads the byte order from that. --- .../uk/co/real_logic/sbe/ir/IrDecoder.java | 11 ++++++- .../sbe/ir/BasicXmlIrGenerationTest.java | 30 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/ir/IrDecoder.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/ir/IrDecoder.java index b7da2ead1c..4db9e04a99 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/ir/IrDecoder.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/ir/IrDecoder.java @@ -126,7 +126,16 @@ public Ir decode() i = captureHeader(tokens); } - final ByteOrder byteOrder = !tokens.isEmpty() ? tokens.get(0).encoding().byteOrder() : null; + ByteOrder byteOrder = null; + for (int j = 0; j < tokens.size(); j++) + { + if (tokens.get(j).signal() == Signal.ENCODING) + { + byteOrder = tokens.get(j).encoding().byteOrder(); + break; + } + } + final Ir ir = new Ir( irPackageName, irNamespaceName, irId, irVersion, null, semanticVersion, byteOrder, irHeader); diff --git a/sbe-tool/src/test/java/uk/co/real_logic/sbe/ir/BasicXmlIrGenerationTest.java b/sbe-tool/src/test/java/uk/co/real_logic/sbe/ir/BasicXmlIrGenerationTest.java index 7f89f2e18d..f3509f7d97 100644 --- a/sbe-tool/src/test/java/uk/co/real_logic/sbe/ir/BasicXmlIrGenerationTest.java +++ b/sbe-tool/src/test/java/uk/co/real_logic/sbe/ir/BasicXmlIrGenerationTest.java @@ -13,15 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package uk.co.real_logic.sbe.ir; -import org.junit.jupiter.api.Test; import uk.co.real_logic.sbe.PrimitiveType; import uk.co.real_logic.sbe.xml.IrGenerator; import uk.co.real_logic.sbe.xml.MessageSchema; import uk.co.real_logic.sbe.xml.ParserOptions; +import org.junit.jupiter.api.Test; import java.io.InputStream; +import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.List; @@ -308,4 +310,30 @@ void shouldGenerateIrForMessageWithVariableLengthFieldWithEmbeddedLength() throw assertThat(tokens.get(dataEncIdx).encoding().primitiveType(), is(PrimitiveType.CHAR)); } } + + @Test + void shouldRegenerateIrWithSameByteOrder() throws Exception + { + try (InputStream in = getLocalResource("example-bigendian-test-schema.xml")) + { + final MessageSchema schema = parse(in, ParserOptions.DEFAULT); + final IrGenerator generator = new IrGenerator(); + final Ir firstIr = generator.generate(schema); + final ByteBuffer firstIrOutputBuffer = ByteBuffer.allocate(8 * 1024); + + final int length; + try (IrEncoder firstIrEncoder = new IrEncoder(firstIrOutputBuffer, firstIr)) + { + length = firstIrEncoder.encode(); + } + + final Ir secondIr; + try (IrDecoder firstIrDecoder = new IrDecoder(firstIrOutputBuffer.slice(0, length))) + { + secondIr = firstIrDecoder.decode(); + } + + assertThat(secondIr.byteOrder(), is(firstIr.byteOrder())); + } + } }