Jason Maskell
Jason Maskell

Reputation: 1816

Proper syntax to read and write byte array in Cap'n Proto?

Let's say I have an array:

struct UUID
{
    char data[16];
};

And I have it like so in the schema:

struct UUID
{
    value @0 : Data;
}

What's the proper way to read and write this field? It looks like I should be able to wrap a capnp::Data::Reader around the array and use the builder's setValue(), but the syntax is really non-obvious.

The other way is also somewhat mysterious. How do I populate the array when deserializing? My current approach involves a memcpy, but I assume there's a Cap'n Proto way to do it.

Upvotes: 2

Views: 1943

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45246

Data::Reader is essentially a kj::ArrayPtr<const kj::byte>.

Data::Builder is essentially a kj::ArrayPtr<kj::byte>.

kj::byte is a typedef for unsigned char.

kj::ArrayPtr is essentially a pointer/size pair. It implements operator[], size(), begin(), end(), etc. begin() and end() return raw pointers, not a special iterator type.

Building:

UUID::Builder builder = ...;
kj::byte buf[16] = ...;

// option 1
builder.setData(kj::arrayPtr(buf, sizeof(buf)));

// option 2
memcpy(builder.initData(16).begin(), buf, 16);

Reading:

UUID::Reader reader = ...;
auto data = reader.getData();

// option 1
// void someFunction(kj::byte* ptr, size_t size)
someFunction(data.begin(), data.size());

// option 2
kj::byte buf[16];
KJ_REQUIRE(data.size() == sizeof(buf));
memcpy(buf, data.begin(), sizeof(buf));

Upvotes: 4

Related Questions