BAR
BAR

Reputation: 17121

Cap'n Proto - Finding Message Size in Java

I am using a TCP Client/Server to send Cap'n Proto messages from C++ to Java.

Sometimes the receiving buffer may be overfilled or underfilled and to handle these cases we need to know the message size.

When I check the size of the buffer in Java I get 208 bytes, however calling

MyModel.MyMessage.STRUCT_SIZE.total()

returns 4 (not sure what unit of measure is being used here).

I notice that 4 divides into 208, 52 times. But I don't know of a significant conversion factor using 52.

How do I check the message size in Java?

Upvotes: 2

Views: 1105

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45246

MyMessage.STRUCT_SIZE represents the constant size of that struct itself (measured in 8-byte words), but if the struct contains non-trivial fields (like Text, Data, List, or other structs) then those take up space too, and the amount of space they take is not constant (e.g. Text will take space according to how long the string is).

Generally you should try to let Cap'n Proto directly write to / read from the appropriate ByteChannels, so that you don't have to keep track of sizes yourself. However, if you really must compute the size of a message ahead of time, you could do so with something like:

ByteBuffer[] segments = message.getSegmentsForOutput();
int total = (segments.length / 2 + 1) * 8;  // segment table
for (ByteBuffer segment: segments) {
  total += segment.remaining();
}
// now `total` is the total number of bytes that will be
// written when the message is serialized.

On the C++ size, you can use capnp::computeSerializedSizeInWords() from serialize.h (and multiply by 8).

But again, you really should structure your code to avoid this, by using the methods of org.capnproto.Serialize with streaming I/O.

Upvotes: 2

Related Questions