1

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.

Jason Maskell
  • 1,716
  • 1
  • 17
  • 26

1 Answers1

3

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));
Kenton Varda
  • 41,353
  • 8
  • 121
  • 105