Допустим, у меня есть массив:
struct UUID
{
char data[16];
};
И у меня это так в схеме:
struct UUID
{
value @0 : Data;
}
Как правильно читать и писать это поле? Похоже, я должен быть в состоянии обернуть capnp :: Data :: Считыватель вокруг массива и используйте метод setValue (), но синтаксис на самом деле неочевиден.
Другой путь тоже несколько загадочный. Как мне заполнить массив при десериализации? Мой нынешний подход предполагает использование memcpy, но я предполагаю, что для этого есть способ Cap’n Proto.
Data::Reader
по сути kj::ArrayPtr<const kj::byte>
,
Data::Builder
по сути kj::ArrayPtr<kj::byte>
,
kj::byte
является typedef для unsigned char
,
kj::ArrayPtr
по сути пара указатель / размер. Это реализует operator[]
, size()
, begin()
, end()
, так далее. begin()
а также end()
возвращать необработанные указатели, а не специальный тип итератора.
Строительство:
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);
Чтение:
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));
Других решений пока нет …