From a462dd5976da33b9698187ac37aa10953c058c61 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Tue, 21 Feb 2023 18:22:52 +0300 Subject: [PATCH 01/14] WIP #509 --- .../openhft/chronicle/wire/Marshallable.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/Marshallable.java b/src/main/java/net/openhft/chronicle/wire/Marshallable.java index f6f74bf4d0..5db6376b34 100644 --- a/src/main/java/net/openhft/chronicle/wire/Marshallable.java +++ b/src/main/java/net/openhft/chronicle/wire/Marshallable.java @@ -17,6 +17,7 @@ */ package net.openhft.chronicle.wire; +import net.openhft.chronicle.core.Jvm; import net.openhft.chronicle.core.annotation.DontChain; import net.openhft.chronicle.core.io.IORuntimeException; import net.openhft.chronicle.core.io.Resettable; @@ -34,12 +35,16 @@ import static net.openhft.chronicle.wire.WireMarshaller.WIRE_MARSHALLER_CL; import static net.openhft.chronicle.wire.WireType.TEXT; +import static net.openhft.chronicle.wire.WireType.YAML; /** * The implementation of this interface is both readable and write-able as marshallable data. */ @DontChain public interface Marshallable extends WriteMarshallable, ReadMarshallable, Resettable { + WireType FROM_STRING_WIRE = Jvm.getBoolean("wire.testAsYaml") + ? YAML : TEXT; + static boolean $equals(@NotNull WriteMarshallable $this, Object o) { return o instanceof WriteMarshallable && ($this == o || Wires.isEquals($this, o)); @@ -50,17 +55,17 @@ public interface Marshallable extends WriteMarshallable, ReadMarshallable, Reset } static String $toString(WriteMarshallable $this) { - return TEXT.asString($this); + return FROM_STRING_WIRE.asString($this); } @Nullable static T fromString(@NotNull CharSequence cs) { - return TEXT.fromString(cs); + return FROM_STRING_WIRE.fromString(cs); } @Nullable static T fromString(@NotNull Class tClass, @NotNull CharSequence cs) { - return TEXT.fromString(tClass, cs); + return FROM_STRING_WIRE.fromString(tClass, cs); } /** @@ -71,12 +76,12 @@ static T fromString(@NotNull Class tClass, @NotNull CharSequence cs) { */ @NotNull static T fromFile(String filename) throws IOException { - return TEXT.fromFile(filename); + return FROM_STRING_WIRE.fromFile(filename); } static T fromString(@NotNull InputStream is) { Scanner s = new Scanner(is).useDelimiter("\\A"); - return TEXT.fromString(s.hasNext() ? s.next() : ""); + return FROM_STRING_WIRE.fromString(s.hasNext() ? s.next() : ""); } /** @@ -88,17 +93,17 @@ static T fromString(@NotNull InputStream is) { */ @Nullable static T fromFile(@NotNull Class expectedType, String filename) throws IOException { - return TEXT.fromFile(expectedType, filename); + return FROM_STRING_WIRE.fromFile(expectedType, filename); } @NotNull static Stream streamFromFile(String filename) throws IOException { - return TEXT.streamFromFile(filename); + return FROM_STRING_WIRE.streamFromFile(filename); } @Nullable static Stream streamFromFile(@NotNull Class expectedType, String filename) throws IOException { - return TEXT.streamFromFile(expectedType, filename); + return FROM_STRING_WIRE.streamFromFile(expectedType, filename); } @Nullable From d3dceca92822143fd8bec414827c8c9536c699d9 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Mon, 27 Feb 2023 23:22:14 +0300 Subject: [PATCH 02/14] Add test for YAML method writer --- src/main/java/net/openhft/chronicle/wire/YamlWire.java | 1 + .../net/openhft/chronicle/wire/ClassAliasPoolTest.java | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 57f126ceec..8db0f277f4 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -193,6 +193,7 @@ public T methodWriter(@NotNull Class tClass, Class... additional) { () -> newTextMethodWriterInvocationHandler(tClass)); for (Class aClass : additional) builder.addInterface(aClass); + useTextDocuments(); builder.marshallableOut(this); return builder.build(); } diff --git a/src/test/java/net/openhft/chronicle/wire/ClassAliasPoolTest.java b/src/test/java/net/openhft/chronicle/wire/ClassAliasPoolTest.java index 329e6365d6..1a98a7c101 100644 --- a/src/test/java/net/openhft/chronicle/wire/ClassAliasPoolTest.java +++ b/src/test/java/net/openhft/chronicle/wire/ClassAliasPoolTest.java @@ -71,6 +71,13 @@ public static Collection data() { "}\n" + "...\n", w.toString())}, + {WireType.YAML, + (Consumer) w -> assertEquals("" + + "handle: !CAPTData {\n" + + " value: 0\n" + + "}\n" + + "...\n", + w.toString())}, {WireType.BINARY, (Consumer) w -> assertEquals("" + "1f 00 00 00 # msg-length\n" + From f19ee89115a481397179ee6ad4144a1e6e41b6e7 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Mon, 27 Feb 2023 23:26:32 +0300 Subject: [PATCH 03/14] Fix test --- src/test/java/net/openhft/chronicle/wire/FIX42Test.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/net/openhft/chronicle/wire/FIX42Test.java b/src/test/java/net/openhft/chronicle/wire/FIX42Test.java index 007619543c..d140c9e75f 100644 --- a/src/test/java/net/openhft/chronicle/wire/FIX42Test.java +++ b/src/test/java/net/openhft/chronicle/wire/FIX42Test.java @@ -163,7 +163,7 @@ public void dump() { @NotNull MarketDataSnapshot mds = new MarketDataSnapshot("EURUSD", 1.1187, 1.1179); mds.writeMarshallable(wire); System.out.println(wire.getClass().getSimpleName() + ", fixed=" + fixed + ", numericField=" + numericField + ", fieldLess=" + fieldLess); - if (wire instanceof TextWire) + if (!wire.isBinary()) assertEquals(dump, wire.bytes().toString()); else assertEquals(dump, wire.bytes().toHexString()); From 90ca92f34c6d30e15576825b74d32c8f56e86b87 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Tue, 28 Feb 2023 12:19:30 +0300 Subject: [PATCH 04/14] Fix compatibility marshallable test --- src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java | 4 ++++ src/main/java/net/openhft/chronicle/wire/YamlWire.java | 1 + .../ForwardAndBackwardCompatibilityMarshallableTest.java | 6 ++---- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java b/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java index a585784758..077ab1ec37 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java @@ -657,6 +657,10 @@ public long lineStart() { return lineStart; } + public void lineStart(long lineStart) { + this.lineStart = lineStart; + } + public long blockStart() { return blockStart; } diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 8db0f277f4..83524d2445 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -250,6 +250,7 @@ protected void initReadContext() { if (readContext == null) useBinaryDocuments(); readContext.start(); + yt.lineStart(bytes.readPosition()); } @NotNull diff --git a/src/test/java/net/openhft/chronicle/wire/ForwardAndBackwardCompatibilityMarshallableTest.java b/src/test/java/net/openhft/chronicle/wire/ForwardAndBackwardCompatibilityMarshallableTest.java index 54c98b86d1..0f0d19aa05 100644 --- a/src/test/java/net/openhft/chronicle/wire/ForwardAndBackwardCompatibilityMarshallableTest.java +++ b/src/test/java/net/openhft/chronicle/wire/ForwardAndBackwardCompatibilityMarshallableTest.java @@ -40,11 +40,12 @@ public ForwardAndBackwardCompatibilityMarshallableTest(WireType wireType) { this.wireType = wireType; } - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Collection data() { return Arrays.asList(new Object[][]{ {WireType.JSON}, {WireType.TEXT}, + {WireType.YAML}, {WireType.BINARY} }); } @@ -58,9 +59,6 @@ public void marshableStringBuilderTest() throws Exception { wire.writeDocument(false, w -> new MDTO2(1, 2, "3").writeMarshallable(w)); // System.out.println(Wires.fromSizePrefixedBlobs(wire)); - if (wire instanceof TextWire) - ((TextWire) wire).useBinaryDocuments(); - try (DocumentContext dc = wire.readingDocument()) { if (!dc.isPresent()) Assert.fail(); From 2dbb5b4633cf88e22e3b8941397ba7298c9f48ef Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Tue, 28 Feb 2023 14:39:05 +0300 Subject: [PATCH 05/14] Fix nested maps test YAML wire --- src/main/java/net/openhft/chronicle/wire/YamlWire.java | 10 +++++++++- .../net/openhft/chronicle/wire/NestedMapsTest.java | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 83524d2445..7872632b14 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -452,6 +452,10 @@ protected StringBuilder readField(@NotNull StringBuilder sb) { public K readEvent(@NotNull Class expectedClass) { startEventIfTop(); switch (yt.current()) { + case MAPPING_START: + yt.next(); + assert yt.current() == YamlToken.MAPPING_KEY; + // Deliberate fall-through case MAPPING_KEY: YamlToken next = yt.next(); if (next == YamlToken.MAPPING_KEY) { @@ -1661,6 +1665,8 @@ public int uint16() { @Override public long int64() { consumePadding(); + if (yt.current() == YamlToken.SEQUENCE_ENTRY) + yt.next(); valueIn.skipType(); if (yt.current() != YamlToken.TEXT) { Jvm.warn().on(getClass(), "Unable to read " + valueIn.object() + " as a long."); @@ -1673,9 +1679,11 @@ public long int64() { @Override public double float64() { consumePadding(); + if (yt.current() == YamlToken.SEQUENCE_ENTRY) + yt.next(); valueIn.skipType(); if (yt.current() != YamlToken.TEXT) { - Jvm.warn().on(getClass(), "Unable to read " + valueIn.object() + " as a long."); + Jvm.warn().on(getClass(), "Unable to read " + valueIn.object() + " as a double."); return 0; } return getADouble(); diff --git a/src/test/java/net/openhft/chronicle/wire/NestedMapsTest.java b/src/test/java/net/openhft/chronicle/wire/NestedMapsTest.java index 9546b33121..49f6374272 100644 --- a/src/test/java/net/openhft/chronicle/wire/NestedMapsTest.java +++ b/src/test/java/net/openhft/chronicle/wire/NestedMapsTest.java @@ -38,11 +38,12 @@ public NestedMapsTest(WireType wireType) { this.wireType = wireType; } - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Collection wireTypes() { return Arrays.asList( new Object[]{WireType.JSON}, new Object[]{WireType.TEXT}, + new Object[]{WireType.YAML}, new Object[]{WireType.BINARY}, new Object[]{WireType.FIELDLESS_BINARY} ); From f94e885fa6b12ee4304b782139f937f1fb8e278f Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Tue, 28 Feb 2023 17:20:37 +0300 Subject: [PATCH 06/14] Fix one of reordering tests --- src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java | 1 + .../net/openhft/chronicle/wire/reordered/ReorderedTest.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java b/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java index 077ab1ec37..43f22b4793 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlTokeniser.java @@ -73,6 +73,7 @@ void reset() { blockQuote = 0; hasSequenceEntry = false; lastKeyPosition = -1; + pushed.clear(); last = YamlToken.STREAM_START; pushContext0(YamlToken.STREAM_START, NO_INDENT); } diff --git a/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java b/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java index 5b0abfa251..3154278e06 100644 --- a/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java +++ b/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java @@ -62,11 +62,12 @@ public ReorderedTest(Function, Wire> wireType) { this.wireType = wireType; } - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Collection combinations() { return Arrays.asList(new Object[][]{ {WireType.JSON}, {WireType.TEXT}, + {WireType.YAML}, {WireType.BINARY} }); } From b1b219606f884eb515ca5a2e51e51e834aba1f6f Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Wed, 1 Mar 2023 02:18:14 +0300 Subject: [PATCH 07/14] Fix text binary wire test against YAML --- .../net/openhft/chronicle/wire/YamlWire.java | 7 ++-- .../chronicle/wire/TextBinaryWireTest.java | 34 ++++++++++--------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 7872632b14..a611e5821e 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -595,11 +595,10 @@ public ValueIn getValueIn() { @NotNull @Override public Wire readComment(@NotNull StringBuilder s) { - sb.setLength(0); + s.setLength(0); if (yt.current() == YamlToken.COMMENT) { - // Skip the initial '#' - YamlToken next = yt.next(); - sb.append(yt.text()); + s.append(yt.text()); + yt.next(); } return this; } diff --git a/src/test/java/net/openhft/chronicle/wire/TextBinaryWireTest.java b/src/test/java/net/openhft/chronicle/wire/TextBinaryWireTest.java index 5248139367..c9bfbe5b44 100644 --- a/src/test/java/net/openhft/chronicle/wire/TextBinaryWireTest.java +++ b/src/test/java/net/openhft/chronicle/wire/TextBinaryWireTest.java @@ -31,6 +31,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; @RunWith(value = Parameterized.class) public class TextBinaryWireTest extends WireTestCommon { @@ -42,13 +44,14 @@ public TextBinaryWireTest(WireType wireType) { this.wireType = wireType; } - @Parameterized.Parameters + @Parameterized.Parameters(name = "{0}") public static Collection combinations() { Object[][] list = { {WireType.BINARY}, {WireType.FIELDLESS_BINARY}, {WireType.RAW}, {WireType.TEXT}, + {WireType.YAML}, {WireType.JSON} }; return Arrays.asList(list); @@ -87,21 +90,21 @@ public void readingDocumentLocation() { @Test public void testReadComment() { - if (wireType == WireType.TEXT || wireType == WireType.BINARY) { - Wire wire = createWire(); - wire.writeComment("This is a comment"); - @NotNull StringBuilder sb = new StringBuilder(); - wire.readComment(sb); - assertEquals("This is a comment", sb.toString()); - - wire.bytes().releaseLast(); - } + assumeTrue(wireType == WireType.TEXT || wireType == WireType.BINARY || wireType == WireType.YAML); + + Wire wire = createWire(); + wire.writeComment("This is a comment"); + @NotNull StringBuilder sb = new StringBuilder(); + wire.readComment(sb); + assertEquals("This is a comment", sb.toString()); + + wire.bytes().releaseLast(); } @Test public void readFieldAsObject() { - if (wireType == WireType.RAW || wireType == WireType.FIELDLESS_BINARY) - return; + assumeFalse(wireType == WireType.RAW || wireType == WireType.FIELDLESS_BINARY); + Wire wire = createWire(); wire.write("CLASS").text("class") .write("RUNTIME").text("runtime"); @@ -117,8 +120,8 @@ public void readFieldAsObject() { @Test public void readFieldAsLong() { - if (wireType == WireType.RAW || wireType == WireType.FIELDLESS_BINARY) - return; + assumeFalse(wireType == WireType.RAW || wireType == WireType.FIELDLESS_BINARY); + Wire wire = createWire(); // todo fix to ensure a field number is used. wire.writeEvent(Long.class, 1L).text("class") @@ -138,8 +141,7 @@ public void readFieldAsLong() { @Test public void testConvertToNum() { - if (wireType == WireType.RAW) - return; + assumeFalse(wireType == WireType.RAW || /* No support for bool conversions */ wireType == WireType.YAML); Wire wire = createWire(); wire.write("a").bool(false) From 7d660eac7a476efdc920c511c0483dc52b609e41 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Wed, 1 Mar 2023 12:37:17 +0300 Subject: [PATCH 08/14] Case insensitive field name matching to match TEXT behavior --- .../chronicle/wire/WireMarshaller.java | 2 +- .../wire/DeserializeFromNakedFileTest.java | 28 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java b/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java index a1e1d6623c..54d78b4dc1 100644 --- a/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java +++ b/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java @@ -342,7 +342,7 @@ public void readMarshallableInputOrder(T t, @NotNull WireIn in, T defaults, bool } public boolean matchesFieldName(StringBuilder sb, FieldAccess field) { - return sb.length() == 0 || StringUtils.isEqual(field.field.getName(), sb); + return sb.length() == 0 || StringUtils.equalsCaseIgnore(field.field.getName(), sb); } public void writeKey(T t, Bytes bytes) { diff --git a/src/test/java/net/openhft/chronicle/wire/DeserializeFromNakedFileTest.java b/src/test/java/net/openhft/chronicle/wire/DeserializeFromNakedFileTest.java index 3bf2e4035c..910ccd0efc 100644 --- a/src/test/java/net/openhft/chronicle/wire/DeserializeFromNakedFileTest.java +++ b/src/test/java/net/openhft/chronicle/wire/DeserializeFromNakedFileTest.java @@ -20,29 +20,51 @@ import net.openhft.chronicle.bytes.BytesMarshallable; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeFalse; +@RunWith(value = Parameterized.class) public class DeserializeFromNakedFileTest extends WireTestCommon { + private final WireType wireType; + + public DeserializeFromNakedFileTest(WireType wireType) { + this.wireType = wireType; + } + + @Parameterized.Parameters(name = "{0}") + public static Collection combinations() { + Object[][] list = { + {WireType.TEXT}, + {WireType.YAML} + }; + return Arrays.asList(list); + } + @Test public void testPOJO() throws IOException { - PlainOldJavaClass res = Marshallable.fromFile(PlainOldJavaClass.class, "naked.yaml"); + PlainOldJavaClass res = wireType.fromFile(PlainOldJavaClass.class, "naked.yaml"); assertEquals(20, res.heartBtInt); } @Test public void testSelfDescribing() throws IOException { - SelfDescribingClass res = Marshallable.fromFile(SelfDescribingClass.class, "naked.yaml"); + SelfDescribingClass res = wireType.fromFile(SelfDescribingClass.class, "naked.yaml"); assertEquals(20, res.heartBtInt); } @Test public void testBytes() throws IOException { - BytesClass res = Marshallable.fromFile(BytesClass.class, "naked.yaml"); + assumeFalse(wireType == WireType.YAML); + BytesClass res = wireType.fromFile(BytesClass.class, "naked.yaml"); // The result of parsing first 4 bytes as integer value assertEquals(0x72616548, res.heartBtInt); From dc9a6d4b18927cf9d9ed9851b69718f766abe96f Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Wed, 1 Mar 2023 14:57:01 +0300 Subject: [PATCH 09/14] Fixed lenient class resolving --- src/main/java/net/openhft/chronicle/wire/YamlWire.java | 8 +++++++- src/test/java/net/openhft/chronicle/wire/WireTests.java | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index a611e5821e..cdddc56f65 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -1459,7 +1459,13 @@ public Type typeLiteral(BiFunction u if (yt.current() == YamlToken.TAG) { if (yt.text().equals("type")) { if (yt.next() == YamlToken.TEXT) { - Class aClass = classLookup().forName(yt.text()); + String text = yt.text(); + Type aClass; + try { + aClass = classLookup().forName(text); + } catch (ClassNotFoundRuntimeException e) { + aClass = unresolvedHandler.apply(text, e.getCause()); + } yt.next(); return aClass; } diff --git a/src/test/java/net/openhft/chronicle/wire/WireTests.java b/src/test/java/net/openhft/chronicle/wire/WireTests.java index 56d3d12644..2c8e979d9e 100644 --- a/src/test/java/net/openhft/chronicle/wire/WireTests.java +++ b/src/test/java/net/openhft/chronicle/wire/WireTests.java @@ -64,6 +64,7 @@ public static Collection data() { {WireType.BINARY, true}, {WireType.BINARY, false}, {WireType.TEXT, false}, + {WireType.YAML, false}, {WireType.JSON, false} }; return Arrays.asList(list); From aaefb1087a791eb25ad4d845dd05a407ae901eea Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Fri, 3 Mar 2023 18:47:07 +0300 Subject: [PATCH 10/14] Fix type literal parsing --- .../java/net/openhft/chronicle/wire/YamlWire.java | 15 ++++++++++++++- .../chronicle/wire/WireSerializedLambdaTest.java | 11 ++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index cdddc56f65..382e2551af 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -1450,7 +1450,20 @@ String stringForCode(int code) { @Override public WireIn typeLiteralAsText(T t, @NotNull BiConsumer classNameConsumer) throws IORuntimeException, BufferUnderflowException { - throw new UnsupportedOperationException(yt.toString()); + if (yt.current() != YamlToken.TAG) + throw new UnsupportedOperationException(yt.toString()); + + if (!yt.isText("type")) + throw new UnsupportedOperationException(yt.text()); + + if (yt.next() != YamlToken.TEXT) + throw new UnsupportedOperationException(yt.toString()); + + StringBuilder stringBuilder = acquireStringBuilder(); + textTo(stringBuilder); + classNameConsumer.accept(t, stringBuilder); + + return YamlWire.this; } @Override diff --git a/src/test/java/net/openhft/chronicle/wire/WireSerializedLambdaTest.java b/src/test/java/net/openhft/chronicle/wire/WireSerializedLambdaTest.java index e71aac581d..fb1cd86be6 100644 --- a/src/test/java/net/openhft/chronicle/wire/WireSerializedLambdaTest.java +++ b/src/test/java/net/openhft/chronicle/wire/WireSerializedLambdaTest.java @@ -55,7 +55,16 @@ public void testIsLambda() { @Test public void testTextWire() { - @NotNull Wire wire = WireType.TEXT.apply(Bytes.elasticByteBuffer()); + textWire(WireType.TEXT); + } + + @Test + public void testYamlWire() { + textWire(WireType.YAML); + } + + private void textWire(WireType wireType) { + @NotNull Wire wire = wireType.apply(Bytes.elasticByteBuffer()); SerializableFunction fun = String::toUpperCase; wire.write(() -> "one").object(fun) From 84db337a9833f189187ea0975f8f36901a611b1b Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Mon, 6 Mar 2023 22:35:53 +0300 Subject: [PATCH 11/14] Fixed handling of sequences --- src/main/java/net/openhft/chronicle/wire/YamlWire.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 382e2551af..0b06747536 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -1320,7 +1320,6 @@ public WireIn sequence(@NotNull T t, K kls, @NotNull TriConsumer Date: Tue, 7 Mar 2023 14:37:58 +0300 Subject: [PATCH 12/14] Support scenario where not all fields are read --- .../net/openhft/chronicle/wire/YamlWire.java | 5 +- .../wire/reordered/NestedReadSubset.java | 68 +++++++++++++++++++ .../wire/reordered/ReorderedTest.java | 18 +++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/test/java/net/openhft/chronicle/wire/reordered/NestedReadSubset.java diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 0b06747536..0377fb62ba 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -734,11 +734,12 @@ public void endEvent() { yt.next(Integer.MIN_VALUE); } else { while (yt.current() == YamlToken.MAPPING_KEY) { - yt.next(); valueIn.consumeAny(minIndent); } } - if (yt.current() == YamlToken.MAPPING_END || yt.current() == YamlToken.DOCUMENT_END || yt.current() == YamlToken.NONE) { + if (yt.current() == YamlToken.MAPPING_END || + yt.current() == YamlToken.DOCUMENT_END || + yt.current() == YamlToken.NONE) { yt.next(Integer.MIN_VALUE); return; } diff --git a/src/test/java/net/openhft/chronicle/wire/reordered/NestedReadSubset.java b/src/test/java/net/openhft/chronicle/wire/reordered/NestedReadSubset.java new file mode 100644 index 0000000000..b6466b71b3 --- /dev/null +++ b/src/test/java/net/openhft/chronicle/wire/reordered/NestedReadSubset.java @@ -0,0 +1,68 @@ +/* + * Copyright 2016-2020 chronicle.software + * + * https://chronicle.software + * + * 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. + */ +package net.openhft.chronicle.wire.reordered; + +import net.openhft.chronicle.core.io.IORuntimeException; +import net.openhft.chronicle.wire.Marshallable; +import net.openhft.chronicle.wire.WireIn; +import net.openhft.chronicle.wire.WireOut; +import org.jetbrains.annotations.NotNull; + +public class NestedReadSubset implements Marshallable { + String text; + String text2; + double number; + double number2; + double number4; + + @Override + public void readMarshallable(@NotNull WireIn wire) throws IORuntimeException { + String text = wire.read("text").text(); + double number = wire.read("number").float64(); + setTextNumber(text, number); + } + + @Override + public void writeMarshallable(@NotNull WireOut wire) { + // write version has way more fields + wire.write(() -> "text").text(text) + .write(() -> "number").float64(number) + .write(() -> "text3").text("is text3") + .write(() -> "number4").float64(number4) + .write(() -> "number3").float64(333.3); + } + + public NestedReadSubset setTextNumber(String text, double number) { + this.text = text; + this.number = number; + this.number4 = number * 4; + return this; + } + + @NotNull + @Override + public String toString() { + return "NestedReadSubset{" + + "text='" + text + '\'' + + ", text2='" + text2 + '\'' + + ", number=" + number + + ", number2=" + number2 + + ", number4=" + number4 + + '}'; + } +} diff --git a/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java b/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java index 3154278e06..3eff854dd1 100644 --- a/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java +++ b/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java @@ -26,6 +26,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.function.Function; @@ -52,10 +53,15 @@ public class ReorderedTest extends WireTestCommon { outerClass1.addListB().setTextNumber("num1BB", 122); outerClass2.addListA().setTextNumber("num2A", 21); outerClass2.addListB().setTextNumber("num2B", 22); + + nestedReadSubsets = Arrays.asList( + new NestedReadSubset().setTextNumber("one", 1.1), + new NestedReadSubset().setTextNumber("two", 2.2)); } @SuppressWarnings("rawtypes") private final Function, Wire> wireType; + private static final Collection nestedReadSubsets; @SuppressWarnings("rawtypes") public ReorderedTest(Function, Wire> wireType) { @@ -97,6 +103,18 @@ public void testWithReorderedFields() { bytes.releaseLast(); } + @Test + public void testWithSubsetFields() { + Bytes bytes = Bytes.elasticByteBuffer(); + Wire wire = wireType.apply(bytes); + wire.writeEventName(() -> "test1").collection(nestedReadSubsets, NestedReadSubset.class); + + @NotNull StringBuilder sb = new StringBuilder(); + + assertEquals(nestedReadSubsets.toString().replace(',', '\n'), wire.readEventName(sb).collection(ArrayList::new, NestedReadSubset.class).toString().replace(',', '\n')); + assertEquals("test1", sb.toString()); + } + @SuppressWarnings("rawtypes") @Test public void testTopLevel() { From 5989ad27d6e050c97fa49d4c9940663afe559f64 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Tue, 7 Mar 2023 15:54:42 +0300 Subject: [PATCH 13/14] Fixed reordered fields test --- src/main/java/net/openhft/chronicle/wire/YamlWire.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/openhft/chronicle/wire/YamlWire.java b/src/main/java/net/openhft/chronicle/wire/YamlWire.java index 0377fb62ba..dded55e128 100644 --- a/src/main/java/net/openhft/chronicle/wire/YamlWire.java +++ b/src/main/java/net/openhft/chronicle/wire/YamlWire.java @@ -538,6 +538,7 @@ public ValueIn read(String keyName) { return valueIn; } } + // Next lines not covered by any tests yt.revertToContext(contextSize); bytes.readPosition(pos); yt.next(); @@ -551,7 +552,8 @@ public ValueIn read(String keyName) { return valueIn; keys.push(lastKeyPosition); - valueIn.consumeAny(minIndent); + // Avoid consuming '}' but consume to next mapping key + valueIn.consumeAny(minIndent >= 0 ? minIndent : Integer.MAX_VALUE); } return defaultValueIn; From 70a25108f3e8ccd3bc919f50944ef43ea74f44f1 Mon Sep 17 00:00:00 2001 From: Ilya Kaznacheev Date: Tue, 7 Mar 2023 17:03:26 +0300 Subject: [PATCH 14/14] Improve test coverage of tricky scenarios --- .../openhft/chronicle/wire/reordered/NestedClass.java | 10 +++++++++- .../chronicle/wire/reordered/ReorderedTest.java | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/test/java/net/openhft/chronicle/wire/reordered/NestedClass.java b/src/test/java/net/openhft/chronicle/wire/reordered/NestedClass.java index 839826b053..eb50e99404 100644 --- a/src/test/java/net/openhft/chronicle/wire/reordered/NestedClass.java +++ b/src/test/java/net/openhft/chronicle/wire/reordered/NestedClass.java @@ -29,11 +29,13 @@ public class NestedClass implements Marshallable { double number; double number2; double number4; // out of order + NestedClass doublyNested; @Override public void readMarshallable(@NotNull WireIn wire) throws IORuntimeException { wire.read(() -> "text").text(this, (t, v) -> t.text = v) .read(() -> "text2").text(this, (t, v) -> t.text2 = v) + .read(() -> "doublyNested").object(NestedClass.class, this, (t, v) -> t.doublyNested = v) .read(() -> "number").float64(this, (t, v) -> t.number = v) .read(() -> "number2").float64(this, (t, v) -> t.number2 = v) .read(() -> "number4").float64(this, (t, v) -> t.number4 = v); @@ -46,13 +48,19 @@ public void writeMarshallable(@NotNull WireOut wire) { .write(() -> "text3").text("is text3") .write(() -> "number4").float64(number4) .write(() -> "number").float64(number) + .write(() -> "doublyNested").object(doublyNested) .write(() -> "number3").float64(333.3); } - public void setTextNumber(String text, double number) { + public NestedClass setTextNumber(String text, double number) { this.text = text; this.number = number; this.number4 = number * 4; + return this; + } + + public void nest(String text, double number) { + this.doublyNested = new NestedClass().setTextNumber(text, number); } @NotNull diff --git a/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java b/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java index 3eff854dd1..60e2541530 100644 --- a/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java +++ b/src/test/java/net/openhft/chronicle/wire/reordered/ReorderedTest.java @@ -48,11 +48,11 @@ public class ReorderedTest extends WireTestCommon { outerClass1.clearListB(); outerClass2.clearListB(); outerClass1.addListA().setTextNumber("num1A", 11); - outerClass1.addListB().setTextNumber("num1B", 12); - outerClass1.addListA().setTextNumber("num1AA", 111); + outerClass1.addListB().setTextNumber("num1B", 12).nest("num1Bbis", 121); + outerClass1.addListA().setTextNumber("num1AA", 111).nest("num1AAbis", 1111); outerClass1.addListB().setTextNumber("num1BB", 122); outerClass2.addListA().setTextNumber("num2A", 21); - outerClass2.addListB().setTextNumber("num2B", 22); + outerClass2.addListB().setTextNumber("num2B", 22).nest("num2Bbis", 222); nestedReadSubsets = Arrays.asList( new NestedReadSubset().setTextNumber("one", 1.1),