capnproto / capnproto-java

Cap'n Proto in pure Java
Other
398 stars 86 forks source link

setting union variant of type List(struct) #83

Closed dwrensha closed 4 years ago

dwrensha commented 4 years ago

Originally posted by @yamass in https://github.com/capnproto/capnproto-java/issues/12#issuecomment-626721459

Model:

struct ClientMessage {
    uuid0 @0 :UInt64;
    uuid1 @1 :UInt64;

    union {
        tv :group {
            x @2 :UInt64;
            y @3 :UInt64;
            z @4 :E;
        }
        data @5 :List(DataFrame);
    }

    enum E {
        e1 @0;
        e2 @1;
    }
}

struct DataFrame {
    timestamp @0 :UInt64;
}

Unit Test:

public class CapnProtoIssue12Test {

    @Test
    public void testUnionWithStructList_writeRead() throws Exception {
        MessageBuilder messageBuilder = new MessageBuilder();
        ClientMessage.Builder clientMessage = messageBuilder.initRoot(ClientMessage.factory);

        StructList.Builder<DataFrame.Builder> dataList = clientMessage.initData(10);
        for (DataFrame.Builder dataFrame : dataList) {
            dataFrame.setTimestamp(123);
        }

        final Path file1 = Files.createTempFile("CapnProtoCopyTest", "");
        try (final FileChannel writeChannel = FileChannel.open(file1, TRUNCATE_EXISTING, WRITE)) {
            Serialize.write(writeChannel, messageBuilder);
        }

        final ClientMessage.Reader clientMessageReader;
        try (final FileChannel readChannel = FileChannel.open(file1, READ)) {
            final MessageReader messageReader = Serialize.read(readChannel);
            clientMessageReader = messageReader.getRoot(ClientMessage.factory);
        }

        Assert.assertTrue(clientMessageReader.isData()); // ===== FAILS =====
    }

    @Test
    public void testUnionWithStructList_usingAsReader() throws Exception {
        MessageBuilder messageBuilder = new MessageBuilder();
        ClientMessage.Builder clientMessage = messageBuilder.initRoot(ClientMessage.factory);

        StructList.Builder<DataFrame.Builder> dataList = clientMessage.initData(10);
        for (DataFrame.Builder dataFrame : dataList) {
            dataFrame.setTimestamp(123);
        }

        Assert.assertTrue(clientMessage.asReader().isData()); // ===== FAILS =====
    }

}
dwrensha commented 4 years ago

@yamass I'm having trouble reproducing this problem. Are you using the latest capnproto-java? What version of the capnp tool do you have? (capnp --version)

yamass commented 4 years ago

You are right, I was using a quite old version (0.5.3) since I was using https://github.com/expretio/capnp-maven-plugin which is totally out of date. Or more precisely, the native binaries are out of date: https://github.com/expretio/capnp-natives. You might want to mention it in the documentation.

My solution was to compile new binaries and release capnp-natives into our company's private repository.

I will write a ticket for capnp-natives. However, I will not provide a pull request, since I did not manage to compile a windows binary. Well, and also because it is quite strange to provide pull requests with binary executables...

yamass commented 4 years ago

Regarding binary distributions: Are there any? (Interested in windows binaries, especially...)

dwrensha commented 4 years ago

I think you were hitting the capnpc-java bug that was fixed in #56.

It would be good to eventually rewrite the schema compiler plugin (capnpc-java) in java, so that the only C++ code needed is the capnp tool.