Commit ebce1a49 authored by Kenton Varda's avatar Kenton Varda

Implemented InlineData, added a bunch of tests for list of lists and such, and fixed tons of bugs.

parent 71afa600
...@@ -40,6 +40,11 @@ struct Text { ...@@ -40,6 +40,11 @@ struct Text {
class Builder; class Builder;
}; };
template <size_t size>
struct InlineData: public Data {};
// Alias for Data used specifically for InlineData fields. This primarily exists so that
// List<InlineData<n>> can be specialized.
class Data::Reader { class Data::Reader {
// Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple // Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple
// pointer which does not own its target, can be passed by value, etc. // pointer which does not own its target, can be passed by value, etc.
......
...@@ -32,6 +32,30 @@ namespace capnproto { ...@@ -32,6 +32,30 @@ namespace capnproto {
namespace internal { namespace internal {
namespace { namespace {
template <typename T, typename U>
void checkList(T reader, std::initializer_list<U> expected) {
ASSERT_EQ(expected.size(), reader.size());
for (uint i = 0; i < expected.size(); i++) {
EXPECT_EQ(expected.begin()[i], reader[i]);
}
}
template <typename T>
void checkList(T reader, std::initializer_list<float> expected) {
ASSERT_EQ(expected.size(), reader.size());
for (uint i = 0; i < expected.size(); i++) {
EXPECT_FLOAT_EQ(expected.begin()[i], reader[i]);
}
}
template <typename T>
void checkList(T reader, std::initializer_list<double> expected) {
ASSERT_EQ(expected.size(), reader.size());
for (uint i = 0; i < expected.size(); i++) {
EXPECT_DOUBLE_EQ(expected.begin()[i], reader[i]);
}
}
TEST(Encoding, AllTypes) { TEST(Encoding, AllTypes) {
MallocMessageBuilder builder; MallocMessageBuilder builder;
...@@ -495,270 +519,21 @@ TEST(Encoding, InitInlineStruct) { ...@@ -495,270 +519,21 @@ TEST(Encoding, InitInlineStruct) {
TEST(Encoding, InlineDefaults) { TEST(Encoding, InlineDefaults) {
MallocMessageBuilder builder; MallocMessageBuilder builder;
TestInlineDefaults::Reader reader = builder.getRoot<TestInlineDefaults>().asReader(); TestInlineDefaults::Builder root = builder.getRoot<TestInlineDefaults>();
{
auto normal = reader.getNormal();
EXPECT_TRUE(normal.getF8().getF0());
EXPECT_FALSE(normal.getF8().getF1());
EXPECT_TRUE(normal.getF8().getF2());
EXPECT_EQ(123u, normal.getF16().getF0());
EXPECT_EQ(45u, normal.getF16().getF1());
EXPECT_EQ(67u, normal.getF32().getF0());
EXPECT_EQ(8901u, normal.getF32().getF1());
EXPECT_EQ(234u, normal.getF64().getF0());
EXPECT_EQ(567890123u, normal.getF64().getF1());
EXPECT_EQ(1234567890123ull, normal.getF128().getF0());
EXPECT_EQ(4567890123456ull, normal.getF128().getF1());
EXPECT_EQ(7890123456789ull, normal.getF192().getF0());
EXPECT_EQ(2345678901234ull, normal.getF192().getF1());
EXPECT_EQ(5678901234567ull, normal.getF192().getF2());
EXPECT_TRUE(normal.getF8p().getF().getF0());
EXPECT_TRUE(normal.getF8p().getF().getF1());
EXPECT_FALSE(normal.getF8p().getF().getF2());
EXPECT_EQ(98u, normal.getF16p().getF().getF0());
EXPECT_EQ(76u, normal.getF16p().getF().getF1());
EXPECT_EQ(54u, normal.getF32p().getF().getF0());
EXPECT_EQ(32109u, normal.getF32p().getF().getF1());
EXPECT_EQ(87u, normal.getF64p().getF().getF0());
EXPECT_EQ(654321098u, normal.getF64p().getF().getF1());
EXPECT_EQ(7654321098765ull, normal.getF128p().getF().getF0());
EXPECT_EQ(4321098765432ull, normal.getF128p().getF().getF1());
EXPECT_EQ(1098765432109ull, normal.getF192p().getF().getF0());
EXPECT_EQ(8765432109876ull, normal.getF192p().getF().getF1());
EXPECT_EQ(5432109876543ull, normal.getF192p().getF().getF2());
EXPECT_EQ("foo", normal.getF0p().getP0());
EXPECT_EQ("baz", normal.getF8p().getP0());
EXPECT_EQ("qux", normal.getF16p().getP0());
EXPECT_EQ("quux", normal.getF16p().getP1());
EXPECT_EQ("corge", normal.getF32p().getP0());
EXPECT_EQ("grault", normal.getF32p().getP1());
EXPECT_EQ("garply", normal.getF64p().getP0());
EXPECT_EQ("waldo", normal.getF64p().getP1());
EXPECT_EQ("fred", normal.getF128p().getP0());
EXPECT_EQ("plugh", normal.getF128p().getP1());
EXPECT_EQ("xyzzy", normal.getF128p().getP2());
EXPECT_EQ("thud", normal.getF192p().getP0());
EXPECT_EQ("foobar", normal.getF192p().getP1());
EXPECT_EQ("barbaz", normal.getF192p().getP2());
}
{ checkTestMessage(root.asReader());
auto unions = reader.getUnions(); checkTestMessage(root);
checkTestMessage(root.asReader());
ASSERT_EQ(TestInlineUnions::Union0::F32, unions.getUnion0().which()); }
EXPECT_EQ(67u, unions.getUnion0().getF32().getF0());
EXPECT_EQ(8901u, unions.getUnion0().getF32().getF1());
ASSERT_EQ(TestInlineUnions::Union1::F128, unions.getUnion1().which());
EXPECT_EQ(1234567890123ull, unions.getUnion1().getF128().getF0());
EXPECT_EQ(4567890123456ull, unions.getUnion1().getF128().getF1());
ASSERT_EQ(TestInlineUnions::Union3::F16P, unions.getUnion3().which());
EXPECT_EQ(98u, unions.getUnion3().getF16p().getF().getF0());
EXPECT_EQ(76u, unions.getUnion3().getF16p().getF().getF1());
EXPECT_EQ("qux", unions.getUnion3().getF16p().getP0());
EXPECT_EQ("quux", unions.getUnion3().getF16p().getP1());
}
{ TEST(Encoding, BuildInlineDefaults) {
auto lists = reader.getLists(); MallocMessageBuilder builder;
TestInlineDefaults::Builder root = builder.getRoot<TestInlineDefaults>();
ASSERT_EQ(2u, lists.getVoidList().size());
ASSERT_EQ(3u, lists.getBoolList().size());
ASSERT_EQ(4u, lists.getUInt8List().size());
ASSERT_EQ(5u, lists.getUInt16List().size());
ASSERT_EQ(6u, lists.getUInt32List().size());
ASSERT_EQ(7u, lists.getUInt64List().size());
ASSERT_EQ(8u, lists.getTextList().size());
ASSERT_EQ(2u, lists.getStructList0().size());
ASSERT_EQ(3u, lists.getStructList1().size());
ASSERT_EQ(4u, lists.getStructList8().size());
ASSERT_EQ(2u, lists.getStructList16().size());
ASSERT_EQ(3u, lists.getStructList32().size());
ASSERT_EQ(4u, lists.getStructList64().size());
ASSERT_EQ(2u, lists.getStructList128().size());
ASSERT_EQ(3u, lists.getStructList192().size());
ASSERT_EQ(4u, lists.getStructList0p().size());
ASSERT_EQ(2u, lists.getStructList1p().size());
ASSERT_EQ(3u, lists.getStructList8p().size());
ASSERT_EQ(4u, lists.getStructList16p().size());
ASSERT_EQ(2u, lists.getStructList32p().size());
ASSERT_EQ(3u, lists.getStructList64p().size());
ASSERT_EQ(4u, lists.getStructList128p().size());
ASSERT_EQ(2u, lists.getStructList192p().size());
EXPECT_EQ(Void::VOID, lists.getVoidList()[0]);
EXPECT_EQ(Void::VOID, lists.getVoidList()[1]);
EXPECT_FALSE(lists.getBoolList()[0]);
EXPECT_TRUE(lists.getBoolList()[1]);
EXPECT_FALSE(lists.getBoolList()[2]);
EXPECT_EQ(12u, lists.getUInt8List()[0]);
EXPECT_EQ(34u, lists.getUInt8List()[1]);
EXPECT_EQ(56u, lists.getUInt8List()[2]);
EXPECT_EQ(78u, lists.getUInt8List()[3]);
EXPECT_EQ(1234u, lists.getUInt16List()[0]);
EXPECT_EQ(5678u, lists.getUInt16List()[1]);
EXPECT_EQ(9012u, lists.getUInt16List()[2]);
EXPECT_EQ(3456u, lists.getUInt16List()[3]);
EXPECT_EQ(7890u, lists.getUInt16List()[4]);
EXPECT_EQ(123456789u, lists.getUInt32List()[0]);
EXPECT_EQ(234567890u, lists.getUInt32List()[1]);
EXPECT_EQ(345678901u, lists.getUInt32List()[2]);
EXPECT_EQ(456789012u, lists.getUInt32List()[3]);
EXPECT_EQ(567890123u, lists.getUInt32List()[4]);
EXPECT_EQ(678901234u, lists.getUInt32List()[5]);
for (uint i = 0; i < 7; i++) {
EXPECT_EQ(i + 1, lists.getUInt64List()[i]);
}
EXPECT_EQ("foo", lists.getTextList()[0]);
EXPECT_EQ("bar", lists.getTextList()[1]);
EXPECT_EQ("baz", lists.getTextList()[2]);
EXPECT_EQ("qux", lists.getTextList()[3]);
EXPECT_EQ("quux", lists.getTextList()[4]);
EXPECT_EQ("corge", lists.getTextList()[5]);
EXPECT_EQ("grault", lists.getTextList()[6]);
EXPECT_EQ("garply", lists.getTextList()[7]);
EXPECT_EQ(Void::VOID, lists.getStructList0()[0].getF());
EXPECT_EQ(Void::VOID, lists.getStructList0()[1].getF());
EXPECT_TRUE (lists.getStructList8()[0].getF0());
EXPECT_FALSE(lists.getStructList8()[0].getF1());
EXPECT_FALSE(lists.getStructList8()[0].getF2());
EXPECT_FALSE(lists.getStructList8()[1].getF0());
EXPECT_TRUE (lists.getStructList8()[1].getF1());
EXPECT_FALSE(lists.getStructList8()[1].getF2());
EXPECT_TRUE (lists.getStructList8()[2].getF0());
EXPECT_TRUE (lists.getStructList8()[2].getF1());
EXPECT_FALSE(lists.getStructList8()[2].getF2());
EXPECT_FALSE(lists.getStructList8()[3].getF0());
EXPECT_FALSE(lists.getStructList8()[3].getF1());
EXPECT_TRUE (lists.getStructList8()[3].getF2());
EXPECT_EQ(12u, lists.getStructList16()[0].getF0());
EXPECT_EQ(34u, lists.getStructList16()[0].getF1());
EXPECT_EQ(56u, lists.getStructList16()[1].getF0());
EXPECT_EQ(78u, lists.getStructList16()[1].getF1());
EXPECT_EQ(90u, lists.getStructList32()[0].getF0());
EXPECT_EQ(12345u, lists.getStructList32()[0].getF1());
EXPECT_EQ(67u, lists.getStructList32()[1].getF0());
EXPECT_EQ(8901u, lists.getStructList32()[1].getF1());
EXPECT_EQ(23u, lists.getStructList32()[2].getF0());
EXPECT_EQ(45678u, lists.getStructList32()[2].getF1());
EXPECT_EQ(90u, lists.getStructList64()[0].getF0());
EXPECT_EQ(123456789u, lists.getStructList64()[0].getF1());
EXPECT_EQ(12u, lists.getStructList64()[1].getF0());
EXPECT_EQ(345678901u, lists.getStructList64()[1].getF1());
EXPECT_EQ(234u, lists.getStructList64()[2].getF0());
EXPECT_EQ(567890123u, lists.getStructList64()[2].getF1());
EXPECT_EQ(45u, lists.getStructList64()[3].getF0());
EXPECT_EQ(678901234u, lists.getStructList64()[3].getF1());
EXPECT_EQ(56789012345678ull, lists.getStructList128()[0].getF0());
EXPECT_EQ(90123456789012ull, lists.getStructList128()[0].getF1());
EXPECT_EQ(34567890123456ull, lists.getStructList128()[1].getF0());
EXPECT_EQ(78901234567890ull, lists.getStructList128()[1].getF1());
EXPECT_EQ(1234567890123ull, lists.getStructList192()[0].getF0());
EXPECT_EQ(4567890123456ull, lists.getStructList192()[0].getF1());
EXPECT_EQ(7890123456789ull, lists.getStructList192()[0].getF2());
EXPECT_EQ( 123456789012ull, lists.getStructList192()[1].getF0());
EXPECT_EQ(3456789012345ull, lists.getStructList192()[1].getF1());
EXPECT_EQ(6789012345678ull, lists.getStructList192()[1].getF2());
EXPECT_EQ(9012345678901ull, lists.getStructList192()[2].getF0());
EXPECT_EQ(2345678901234ull, lists.getStructList192()[2].getF1());
EXPECT_EQ(5678901234567ull, lists.getStructList192()[2].getF2());
EXPECT_EQ("foo", lists.getStructList0p()[0].getP0());
EXPECT_EQ("bar", lists.getStructList0p()[1].getP0());
EXPECT_EQ("baz", lists.getStructList0p()[2].getP0());
EXPECT_EQ("qux", lists.getStructList0p()[3].getP0());
EXPECT_TRUE(lists.getStructList8p()[0].getF().getF0());
EXPECT_EQ("grault", lists.getStructList8p()[0].getP0());
EXPECT_EQ("garply", lists.getStructList8p()[1].getP0());
EXPECT_EQ("waldo", lists.getStructList8p()[2].getP0());
EXPECT_EQ(123u, lists.getStructList16p()[0].getF().getF0());
EXPECT_EQ("fred", lists.getStructList16p()[0].getP0());
EXPECT_EQ("plugh", lists.getStructList16p()[0].getP1());
EXPECT_EQ("xyzzy", lists.getStructList16p()[1].getP0());
EXPECT_EQ("thud", lists.getStructList16p()[1].getP1());
EXPECT_EQ("foobar", lists.getStructList16p()[2].getP0());
EXPECT_EQ("barbaz", lists.getStructList16p()[2].getP1());
EXPECT_EQ("bazqux", lists.getStructList16p()[3].getP0());
EXPECT_EQ("quxquux", lists.getStructList16p()[3].getP1());
EXPECT_EQ(12345u, lists.getStructList32p()[0].getF().getF1());
EXPECT_EQ("quuxcorge", lists.getStructList32p()[0].getP0());
EXPECT_EQ("corgegrault", lists.getStructList32p()[0].getP1());
EXPECT_EQ("graultgarply", lists.getStructList32p()[1].getP0());
EXPECT_EQ("garplywaldo", lists.getStructList32p()[1].getP1());
EXPECT_EQ(123456789u, lists.getStructList64p()[0].getF().getF1());
EXPECT_EQ("waldofred", lists.getStructList64p()[0].getP0());
EXPECT_EQ("fredplugh", lists.getStructList64p()[0].getP1());
EXPECT_EQ("plughxyzzy", lists.getStructList64p()[1].getP0());
EXPECT_EQ("xyzzythud", lists.getStructList64p()[1].getP1());
EXPECT_EQ("thudfoo", lists.getStructList64p()[2].getP0());
EXPECT_EQ("foofoo", lists.getStructList64p()[2].getP1());
EXPECT_EQ(123456789012345ull, lists.getStructList128p()[0].getF().getF1());
EXPECT_EQ("foobaz", lists.getStructList128p()[0].getP0());
EXPECT_EQ("fooqux", lists.getStructList128p()[0].getP1());
EXPECT_EQ("foocorge", lists.getStructList128p()[0].getP2());
EXPECT_EQ("barbaz", lists.getStructList128p()[1].getP0());
EXPECT_EQ("barqux", lists.getStructList128p()[1].getP1());
EXPECT_EQ("barcorge", lists.getStructList128p()[1].getP2());
EXPECT_EQ("bazbaz", lists.getStructList128p()[2].getP0());
EXPECT_EQ("bazqux", lists.getStructList128p()[2].getP1());
EXPECT_EQ("bazcorge", lists.getStructList128p()[2].getP2());
EXPECT_EQ("quxbaz", lists.getStructList128p()[3].getP0());
EXPECT_EQ("quxqux", lists.getStructList128p()[3].getP1());
EXPECT_EQ("quxcorge", lists.getStructList128p()[3].getP2());
EXPECT_EQ(123456789012345ull, lists.getStructList192p()[0].getF().getF2());
EXPECT_EQ("corgebaz", lists.getStructList192p()[0].getP0());
EXPECT_EQ("corgequx", lists.getStructList192p()[0].getP1());
EXPECT_EQ("corgecorge", lists.getStructList192p()[0].getP2());
EXPECT_EQ("graultbaz", lists.getStructList192p()[1].getP0());
EXPECT_EQ("graultqux", lists.getStructList192p()[1].getP1());
EXPECT_EQ("graultcorge", lists.getStructList192p()[1].getP2());
}
{ initTestMessage(root);
auto sl = reader.getStructLists(); checkTestMessage(root.asReader());
checkTestMessage(root);
ASSERT_EQ(2u, sl.getList0().size()); checkTestMessage(root.asReader());
ASSERT_EQ(2u, sl.getList1().size());
ASSERT_EQ(2u, sl.getList8().size());
ASSERT_EQ(2u, sl.getList16().size());
ASSERT_EQ(2u, sl.getList32().size());
ASSERT_EQ(2u, sl.getList64().size());
ASSERT_EQ(2u, sl.getListP().size());
EXPECT_EQ(Void::VOID, sl.getList0()[0].getF());
EXPECT_EQ(Void::VOID, sl.getList0()[1].getF());
EXPECT_TRUE(sl.getList1()[0].getF());
EXPECT_FALSE(sl.getList1()[1].getF());
EXPECT_EQ(123u, sl.getList8()[0].getF());
EXPECT_EQ(45u, sl.getList8()[1].getF());
EXPECT_EQ(12345u, sl.getList16()[0].getF());
EXPECT_EQ(6789u, sl.getList16()[1].getF());
EXPECT_EQ(123456789u, sl.getList32()[0].getF());
EXPECT_EQ(234567890u, sl.getList32()[1].getF());
EXPECT_EQ(1234567890123456u, sl.getList64()[0].getF());
EXPECT_EQ(2345678901234567u, sl.getList64()[1].getF());
EXPECT_EQ("foo", sl.getListP()[0].getF());
EXPECT_EQ("bar", sl.getListP()[1].getF());
}
} }
TEST(Encoding, SmallStructLists) { TEST(Encoding, SmallStructLists) {
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "util.h" #include "util.h"
#include "logging.h" #include "logging.h"
#include <unistd.h> #include <unistd.h>
#include <execinfo.h>
#include <stdlib.h>
namespace capnproto { namespace capnproto {
...@@ -59,10 +61,15 @@ Exception::Exception(Nature nature, Durability durability, const char* file, int ...@@ -59,10 +61,15 @@ Exception::Exception(Nature nature, Durability durability, const char* file, int
description(move(description)) { description(move(description)) {
bool hasDescription = this->description != nullptr; bool hasDescription = this->description != nullptr;
void* trace[16];
int traceCount = backtrace(trace, 16);
ArrayPtr<void*> traceArray = arrayPtr(trace, traceCount);
// Must be careful to NUL-terminate this. // Must be careful to NUL-terminate this.
whatStr = str(file, ":", line, ": ", nature, whatStr = str(file, ":", line, ": ", nature,
durability == Durability::TEMPORARY ? " (temporary)" : "", durability == Durability::TEMPORARY ? " (temporary)" : "",
hasDescription ? ": " : "", this->description, '\0'); hasDescription ? ": " : "", this->description,
"\nstack: ", strArray(traceArray, " "), '\0');
} }
Exception::Exception(const Exception& other) noexcept Exception::Exception(const Exception& other) noexcept
......
...@@ -364,6 +364,14 @@ public: ...@@ -364,6 +364,14 @@ public:
const void* defaultValue, ByteCount defaultSize) const; const void* defaultValue, ByteCount defaultSize) const;
// Same as *Text*, but for data blobs. // Same as *Text*, but for data blobs.
CAPNPROTO_ALWAYS_INLINE(Data::Builder getInlineDataField(
ByteCount offset, ByteCount size) const);
CAPNPROTO_ALWAYS_INLINE(void setInlineDataField(
ByteCount offset, ByteCount size, Data::Reader value) const);
CAPNPROTO_ALWAYS_INLINE(Data::Builder initInlineDataField(
ByteCount offset, ByteCount size) const);
// For InlineData.
StructReader asReader() const; StructReader asReader() const;
// Gets a StructReader pointing at the same memory. // Gets a StructReader pointing at the same memory.
...@@ -445,6 +453,10 @@ public: ...@@ -445,6 +453,10 @@ public:
const void* defaultValue, ByteCount defaultSize) const; const void* defaultValue, ByteCount defaultSize) const;
// Gets the data field, or the given default value if not initialized. // Gets the data field, or the given default value if not initialized.
CAPNPROTO_ALWAYS_INLINE(Data::Reader getInlineDataField(
ByteCount offset, ByteCount size) const);
// Gets the inline data field.
WireReferenceCount getReferenceCount() { return referenceCount; } WireReferenceCount getReferenceCount() { return referenceCount; }
private: private:
...@@ -509,6 +521,10 @@ public: ...@@ -509,6 +521,10 @@ public:
// Get the existing list element at the given index. Returns an empty list if the element is // Get the existing list element at the given index. Returns an empty list if the element is
// not initialized. // not initialized.
CAPNPROTO_ALWAYS_INLINE(ListBuilder slice(ElementCount start, ElementCount length) const);
// Get a list pointing at a slice of this list. WARNING: The second parameter is a length, not
// an end index, because this is what is most convenient at the only call site.
Text::Builder initTextElement(ElementCount index, ByteCount size) const; Text::Builder initTextElement(ElementCount index, ByteCount size) const;
// Initialize the text element to the given size in bytes (not including NUL terminator) and // Initialize the text element to the given size in bytes (not including NUL terminator) and
// return a Text::Builder which can be used to fill in the content. // return a Text::Builder which can be used to fill in the content.
...@@ -522,6 +538,7 @@ public: ...@@ -522,6 +538,7 @@ public:
Data::Builder initDataElement(ElementCount index, ByteCount size) const; Data::Builder initDataElement(ElementCount index, ByteCount size) const;
void setDataElement(ElementCount index, Data::Reader value) const; void setDataElement(ElementCount index, Data::Reader value) const;
Data::Builder getDataElement(ElementCount index) const; Data::Builder getDataElement(ElementCount index) const;
// Like *Text*() but for Data.
ListReader asReader(FieldSize elementSize) const; ListReader asReader(FieldSize elementSize) const;
// Get a ListReader pointing at the same memory. Use this version only for non-struct lists. // Get a ListReader pointing at the same memory. Use this version only for non-struct lists.
...@@ -573,6 +590,10 @@ public: ...@@ -573,6 +590,10 @@ public:
ListReader getListElement(ElementCount index, FieldSize expectedElementSize) const; ListReader getListElement(ElementCount index, FieldSize expectedElementSize) const;
// Get the list element at the given index. // Get the list element at the given index.
CAPNPROTO_ALWAYS_INLINE(ListReader slice(ElementCount start, ElementCount length) const);
// Get a list pointing at a slice of this list. WARNING: The second parameter is a length, not
// an end index, because this is what is most convenient at the only call site.
Text::Reader getTextElement(ElementCount index) const; Text::Reader getTextElement(ElementCount index) const;
// Get the text element. If it is not initialized, returns an empty Text::Reader. // Get the text element. If it is not initialized, returns an empty Text::Reader.
...@@ -741,6 +762,22 @@ inline ListBuilder StructBuilder::getInlineStructListField( ...@@ -741,6 +762,22 @@ inline ListBuilder StructBuilder::getInlineStructListField(
elementCount); elementCount);
} }
inline Data::Builder StructBuilder::getInlineDataField(
ByteCount offset, ByteCount size) const {
return Data::Builder(
reinterpret_cast<char*>(reinterpret_cast<byte*>(data) + offset), size / BYTES);
}
inline void StructBuilder::setInlineDataField(
ByteCount offset, ByteCount size, Data::Reader value) const {
getInlineDataField(offset, size).copyFrom(value);
}
inline Data::Builder StructBuilder::initInlineDataField(
ByteCount offset, ByteCount size) const {
byte* ptr = reinterpret_cast<byte*>(data) + offset;
memset(ptr, 0, size / BYTES);
return Data::Builder(reinterpret_cast<char*>(ptr), size / BYTES);
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
template <typename T> template <typename T>
...@@ -776,17 +813,20 @@ T StructReader::getDataField(ElementCount offset, typename MaskType<T>::Type mas ...@@ -776,17 +813,20 @@ T StructReader::getDataField(ElementCount offset, typename MaskType<T>::Type mas
inline StructReader StructReader::getInlineStructField( inline StructReader StructReader::getInlineStructField(
ByteCount dataOffset, ByteCount inlineDataSize, ByteCount dataOffset, ByteCount inlineDataSize,
WireReferenceCount refIndex, WireReferenceCount inlineRefCount) const { WireReferenceCount refIndex, WireReferenceCount inlineRefCount) const {
// TODO(soon): Too complicated to be inlined?
return StructReader( return StructReader(
segment, reinterpret_cast<const byte*>(data) + dataOffset, segment, reinterpret_cast<const byte*>(data) + dataOffset,
// WireReference is incomplete here so we have to cast around... Bah. // WireReference is incomplete here so we have to cast around... Bah.
reinterpret_cast<const WireReference*>( reinterpret_cast<const WireReference*>(
reinterpret_cast<const word*>(references) + refIndex * WORDS_PER_REFERENCE), reinterpret_cast<const word*>(references) + refIndex * WORDS_PER_REFERENCE),
dataSize, inlineRefCount, inlineDataSize * (dataOffset + inlineDataSize <= dataSize),
inlineRefCount * (refIndex + inlineRefCount <= referenceCount),
nestingLimit); nestingLimit);
} }
inline ListReader StructReader::getInlineDataListField( inline ListReader StructReader::getInlineDataListField(
ByteCount offset, ElementCount elementCount, FieldSize elementSize) const { ByteCount offset, ElementCount elementCount, FieldSize elementSize) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return ListReader( return ListReader(
segment, reinterpret_cast<const byte*>(data) + offset, nullptr, segment, reinterpret_cast<const byte*>(data) + offset, nullptr,
elementCount, bytesPerElement(elementSize), 0 * REFERENCES / ELEMENTS, elementCount, bytesPerElement(elementSize), 0 * REFERENCES / ELEMENTS,
...@@ -795,6 +835,7 @@ inline ListReader StructReader::getInlineDataListField( ...@@ -795,6 +835,7 @@ inline ListReader StructReader::getInlineDataListField(
inline ListReader StructReader::getInlinePointerListField( inline ListReader StructReader::getInlinePointerListField(
WireReferenceCount offset, ElementCount elementCount) const { WireReferenceCount offset, ElementCount elementCount) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return ListReader( return ListReader(
segment, nullptr, segment, nullptr,
reinterpret_cast<const WireReference*>( reinterpret_cast<const WireReference*>(
...@@ -806,6 +847,7 @@ inline ListReader StructReader::getInlinePointerListField( ...@@ -806,6 +847,7 @@ inline ListReader StructReader::getInlinePointerListField(
inline ListReader StructReader::getInlineStructListField( inline ListReader StructReader::getInlineStructListField(
ByteCount dataOffset, WireReferenceCount ptrOffset, ElementCount elementCount, ByteCount dataOffset, WireReferenceCount ptrOffset, ElementCount elementCount,
StructSize elementSize) const { StructSize elementSize) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return ListReader( return ListReader(
segment, reinterpret_cast<const byte*>(data) + dataOffset, segment, reinterpret_cast<const byte*>(data) + dataOffset,
reinterpret_cast<const WireReference*>( reinterpret_cast<const WireReference*>(
...@@ -814,6 +856,12 @@ inline ListReader StructReader::getInlineStructListField( ...@@ -814,6 +856,12 @@ inline ListReader StructReader::getInlineStructListField(
elementSize.dataBytes, elementSize.pointers, nestingLimit); elementSize.dataBytes, elementSize.pointers, nestingLimit);
} }
inline Data::Reader StructReader::getInlineDataField(ByteCount offset, ByteCount size) const {
// TODO(soon): Bounds check! Needs to fall back to some common zero'd region.
return Data::Reader(reinterpret_cast<const char*>(reinterpret_cast<const byte*>(data) + offset),
size / BYTES);
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
inline ElementCount ListBuilder::size() { return elementCount; } inline ElementCount ListBuilder::size() { return elementCount; }
...@@ -856,6 +904,14 @@ inline void ListBuilder::setDataElement<bool>(ElementCount index, bool value) co ...@@ -856,6 +904,14 @@ inline void ListBuilder::setDataElement<bool>(ElementCount index, bool value) co
template <> template <>
inline void ListBuilder::setDataElement<Void>(ElementCount index, Void value) const {} inline void ListBuilder::setDataElement<Void>(ElementCount index, Void value) const {}
inline ListBuilder ListBuilder::slice(ElementCount start, ElementCount length) const {
return ListBuilder(segment,
reinterpret_cast<byte*>(data) + start * stepBytes,
reinterpret_cast<WireReference*>(
reinterpret_cast<word*>(pointers) + start * stepPointers * WORDS_PER_REFERENCE),
stepBytes, stepPointers, length);
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
inline ElementCount ListReader::size() { return elementCount; } inline ElementCount ListReader::size() { return elementCount; }
...@@ -879,6 +935,14 @@ inline Void ListReader::getDataElement<Void>(ElementCount index) const { ...@@ -879,6 +935,14 @@ inline Void ListReader::getDataElement<Void>(ElementCount index) const {
return Void::VOID; return Void::VOID;
} }
inline ListReader ListReader::slice(ElementCount start, ElementCount length) const {
return ListReader(segment,
reinterpret_cast<const byte*>(data) + start * stepBytes,
reinterpret_cast<const WireReference*>(
reinterpret_cast<const word*>(pointers) + start * stepPointers * WORDS_PER_REFERENCE),
length, stepBytes, stepPointers, structDataSize, structReferenceCount, nestingLimit);
}
} // namespace internal } // namespace internal
} // namespace capnproto } // namespace capnproto
......
...@@ -48,6 +48,10 @@ public: ...@@ -48,6 +48,10 @@ public:
template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value> template <typename T, bool isPrimitive = internal::IsPrimitive<T>::value>
struct List; struct List;
template <typename T, size_t size>
struct InlineList: public List<T> {};
// Alias for List. Primarily exists so that we can specialize List<InlineList<...>>.
namespace internal { namespace internal {
template <size_t size> struct FieldSizeForByteSize; template <size_t size> struct FieldSizeForByteSize;
...@@ -146,6 +150,8 @@ private: ...@@ -146,6 +150,8 @@ private:
template <typename T> template <typename T>
struct List<T, true> { struct List<T, true> {
// List of primitives.
class Reader { class Reader {
public: public:
Reader() = default; Reader() = default;
...@@ -207,10 +213,29 @@ struct List<T, true> { ...@@ -207,10 +213,29 @@ struct List<T, true> {
private: private:
internal::ListBuilder builder; internal::ListBuilder builder;
}; };
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSizeForType<T>::value, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSizeForType<T>::value);
}
template <typename U, bool b>
friend class List;
}; };
template <typename T> template <typename T>
struct List<T, false> { struct List<T, false> {
// List of structs.
class Reader { class Reader {
public: public:
Reader() = default; Reader() = default;
...@@ -251,10 +276,29 @@ struct List<T, false> { ...@@ -251,10 +276,29 @@ struct List<T, false> {
private: private:
internal::ListBuilder builder; internal::ListBuilder builder;
}; };
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initStructListElement(
index * ELEMENTS, size * ELEMENTS, T::STRUCT_SIZE);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::INLINE_COMPOSITE);
}
template <typename U, bool b>
friend class List;
}; };
template <typename T> template <typename T>
struct List<List<T>, true> { struct List<List<T>, false> {
// List of lists.
class Reader { class Reader {
public: public:
Reader() = default; Reader() = default;
...@@ -262,8 +306,7 @@ struct List<List<T>, true> { ...@@ -262,8 +306,7 @@ struct List<List<T>, true> {
inline uint size() { return reader.size() / ELEMENTS; } inline uint size() { return reader.size() / ELEMENTS; }
inline typename List<T>::Reader operator[](uint index) { inline typename List<T>::Reader operator[](uint index) {
return typename List<T>::Reader(reader.getListElement(index * REFERENCES, return typename List<T>::Reader(List<T>::getAsElementOf(reader, index));
internal::FieldSizeForType<T>::value));
} }
typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator; typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator;
...@@ -281,11 +324,10 @@ struct List<List<T>, true> { ...@@ -281,11 +324,10 @@ struct List<List<T>, true> {
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS; }
inline typename List<T>::Builder operator[](uint index) { inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * ELEMENTS)); return typename List<T>::Builder(List<T>::getAsElementOf(builder, index));
} }
inline typename List<T>::Builder init(uint index, uint size) { inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initListElement( return typename List<T>::Builder(List<T>::initAsElementOf(builder, index, size));
index * ELEMENTS, internal::FieldSizeForType<T>::value, size * ELEMENTS));
} }
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator; typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
...@@ -300,19 +342,38 @@ struct List<List<T>, true> { ...@@ -300,19 +342,38 @@ struct List<List<T>, true> {
private: private:
internal::ListBuilder builder; internal::ListBuilder builder;
}; };
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::REFERENCE);
}
template <typename U, bool b>
friend class List;
}; };
template <typename T> template <typename T, size_t subSize>
struct List<List<T>, false> { struct List<InlineList<T, subSize>, false> {
// List of inline lists.
class Reader { class Reader {
public: public:
Reader() = default; Reader() = default;
inline explicit Reader(internal::ListReader reader): reader(reader) {} inline explicit Reader(internal::ListReader reader): reader(reader) {}
inline uint size() { return reader.size() / ELEMENTS; } inline uint size() { return reader.size() / ELEMENTS / subSize; }
inline typename List<T>::Reader operator[](uint index) { inline typename List<T>::Reader operator[](uint index) {
return typename List<T>::Reader(reader.getListElement(index * ELEMENTS, return typename List<T>::Reader(reader.slice(
internal::FieldSizeForType<T>::value)); index * subSize * ELEMENTS, subSize * ELEMENTS));
} }
typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator; typedef internal::IndexingIterator<Reader, typename List<T>::Reader> iterator;
...@@ -328,13 +389,10 @@ struct List<List<T>, false> { ...@@ -328,13 +389,10 @@ struct List<List<T>, false> {
Builder() = default; Builder() = default;
inline explicit Builder(internal::ListBuilder builder): builder(builder) {} inline explicit Builder(internal::ListBuilder builder): builder(builder) {}
inline uint size() { return builder.size() / ELEMENTS; } inline uint size() { return builder.size() / ELEMENTS / subSize; }
inline typename List<T>::Builder operator[](uint index) { inline typename List<T>::Builder operator[](uint index) {
return typename List<T>::Builder(builder.getListElement(index * ELEMENTS)); return typename List<T>::Builder(builder.slice(
} index * subSize * ELEMENTS, subSize * ELEMENTS));
inline typename List<T>::Builder init(uint index, uint size) {
return typename List<T>::Builder(builder.initStructListElement(
index * ELEMENTS, size * ELEMENTS, T::DEFAULT.words));
} }
typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator; typedef internal::IndexingIterator<Builder, typename List<T>::Builder> iterator;
...@@ -349,6 +407,22 @@ struct List<List<T>, false> { ...@@ -349,6 +407,22 @@ struct List<List<T>, false> {
private: private:
internal::ListBuilder builder; internal::ListBuilder builder;
}; };
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return List<T>::initAsElementOf(builder, index, size * subSize);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSizeForType<T>::value);
}
template <typename U, bool b>
friend class List;
}; };
template <> template <>
...@@ -413,6 +487,104 @@ struct List<Data, false> { ...@@ -413,6 +487,104 @@ struct List<Data, false> {
private: private:
internal::ListBuilder builder; internal::ListBuilder builder;
}; };
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::REFERENCE);
}
template <typename U, bool b>
friend class List;
};
template <size_t subSize>
struct List<InlineData<subSize>, false> {
// List of inline lists.
class Reader {
public:
Reader() = default;
inline explicit Reader(Data::Reader reader): reader(reader) {}
inline uint size() { return reader.size() / subSize; }
inline typename Data::Reader operator[](uint index) {
return typename Data::Reader(reader.slice(
index * subSize, index * subSize + subSize));
}
typedef internal::IndexingIterator<Reader, typename Data::Reader> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
private:
Data::Reader reader;
};
class Builder {
public:
Builder() = default;
inline explicit Builder(Data::Builder builder): builder(builder) {}
inline uint size() { return builder.size() / subSize; }
inline typename Data::Builder operator[](uint index) {
return typename Data::Builder(builder.slice(
index * subSize, index * subSize + subSize));
}
inline void set(uint index, Data::Reader value) {
(*this)[index].copyFrom(value);
}
typedef internal::IndexingIterator<Builder, typename Data::Builder> iterator;
inline iterator begin() { return iterator(this, 0); }
inline iterator end() { return iterator(this, size()); }
template <typename Other>
void copyFrom(const Other& other) {
auto i = other.begin();
auto end = other.end();
uint pos = 0;
for (; i != end && pos < size(); ++i) {
set(pos, *i);
}
CAPNPROTO_INLINE_DPRECOND(pos == size() && i == end,
"List::copyFrom() argument had different size.");
}
void copyFrom(std::initializer_list<Data::Reader> other) {
CAPNPROTO_INLINE_DPRECOND(other.size() == size(),
"List::copyFrom() argument had different size.");
for (uint i = 0; i < other.size(); i++) {
set(i, other.begin()[i]);
}
}
private:
Data::Builder builder;
};
private:
inline static Data::Builder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initDataElement(index * ELEMENTS, size * subSize * BYTES);
}
inline static Data::Builder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getDataElement(index * ELEMENTS);
}
inline static Data::Reader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getDataElement(index * ELEMENTS);
}
template <typename U, bool b>
friend class List;
}; };
template <> template <>
...@@ -477,6 +649,23 @@ struct List<Text, false> { ...@@ -477,6 +649,23 @@ struct List<Text, false> {
private: private:
internal::ListBuilder builder; internal::ListBuilder builder;
}; };
private:
inline static internal::ListBuilder initAsElementOf(
internal::ListBuilder& builder, uint index, uint size) {
return builder.initListElement(
index * ELEMENTS, internal::FieldSize::REFERENCE, size * ELEMENTS);
}
inline static internal::ListBuilder getAsElementOf(
internal::ListBuilder& builder, uint index) {
return builder.getListElement(index * ELEMENTS);
}
inline static internal::ListReader getAsElementOf(
internal::ListReader& reader, uint index) {
return reader.getListElement(index * ELEMENTS, internal::FieldSize::REFERENCE);
}
template <typename U, bool b>
friend class List;
}; };
} // namespace capnproto } // namespace capnproto
......
...@@ -45,13 +45,27 @@ public: ...@@ -45,13 +45,27 @@ public:
void onRecoverableException(Exception&& exception) override { void onRecoverableException(Exception&& exception) override {
text += "recoverable exception: "; text += "recoverable exception: ";
text += exception.what(); // Only take the first line of "what" because the second line is a stack trace.
const char* what = exception.what();
const char* end = strchr(what, '\n');
if (end == nullptr) {
text += exception.what();
} else {
text.append(what, end);
}
text += '\n'; text += '\n';
} }
void onFatalException(Exception&& exception) override { void onFatalException(Exception&& exception) override {
text += "fatal exception: "; text += "fatal exception: ";
text += exception.what(); // Only take the first line of "what" because the second line is a stack trace.
const char* what = exception.what();
const char* end = strchr(what, '\n');
if (end == nullptr) {
text += exception.what();
} else {
text.append(what, end);
}
text += '\n'; text += '\n';
throw MockException(); throw MockException();
} }
......
...@@ -324,16 +324,847 @@ void genericCheckTestMessageAllZero(Reader reader) { ...@@ -324,16 +324,847 @@ void genericCheckTestMessageAllZero(Reader reader) {
EXPECT_EQ(0u, reader.getStructList().size()); EXPECT_EQ(0u, reader.getStructList().size());
} }
template <typename Builder>
void genericInitInlineDefaults(Builder builder) {
{
auto normal = builder.initNormal();
normal.getF8().setF0(true);
normal.getF8().setF1(false);
normal.getF8().setF2(true);
normal.getF16().setF0(123u);
normal.getF16().setF1(45u);
normal.getF32().setF0(67u);
normal.getF32().setF1(8901u);
normal.getF64().setF0(234u);
normal.getF64().setF1(567890123u);
normal.getF128().setF0(1234567890123ull);
normal.getF128().setF1(4567890123456ull);
normal.getF192().setF0(7890123456789ull);
normal.getF192().setF1(2345678901234ull);
normal.getF192().setF2(5678901234567ull);
normal.getF8p().getF().setF0(true);
normal.getF8p().getF().setF1(true);
normal.getF8p().getF().setF2(false);
normal.getF16p().getF().setF0(98u);
normal.getF16p().getF().setF1(76u);
normal.getF32p().getF().setF0(54u);
normal.getF32p().getF().setF1(32109u);
normal.getF64p().getF().setF0(87u);
normal.getF64p().getF().setF1(654321098u);
normal.getF128p().getF().setF0(7654321098765ull);
normal.getF128p().getF().setF1(4321098765432ull);
normal.getF192p().getF().setF0(1098765432109ull);
normal.getF192p().getF().setF1(8765432109876ull);
normal.getF192p().getF().setF2(5432109876543ull);
normal.getF0p().setP0("foo");
normal.getF8p().setP0("baz");
normal.getF16p().setP0("qux");
normal.getF16p().setP1("quux");
normal.getF32p().setP0("corge");
normal.getF32p().setP1("grault");
normal.getF64p().setP0("garply");
normal.getF64p().setP1("waldo");
normal.getF128p().setP0("fred");
normal.getF128p().setP1("plugh");
normal.getF128p().setP2("xyzzy");
normal.getF192p().setP0("thud");
normal.getF192p().setP1("foobar");
normal.getF192p().setP2("barbaz");
}
{
auto unions = builder.initUnions();
unions.getUnion0().initF32().setF0(67u);
unions.getUnion0().getF32().setF1(8901u);
unions.getUnion1().initF128().setF0(1234567890123ull);
unions.getUnion1().getF128().setF1(4567890123456ull);
unions.getUnion3().initF16p().getF().setF0(98u);
unions.getUnion3().getF16p().getF().setF1(76u);
unions.getUnion3().getF16p().setP0("qux");
unions.getUnion3().getF16p().setP1("quux");
}
{
auto lists = builder.initLists();
ASSERT_EQ(2u, lists.getVoidList().size());
ASSERT_EQ(3u, lists.getBoolList().size());
ASSERT_EQ(4u, lists.getUInt8List().size());
ASSERT_EQ(5u, lists.getUInt16List().size());
ASSERT_EQ(6u, lists.getUInt32List().size());
ASSERT_EQ(7u, lists.getUInt64List().size());
ASSERT_EQ(8u, lists.getTextList().size());
ASSERT_EQ(2u, lists.getStructList0().size());
ASSERT_EQ(3u, lists.getStructList1().size());
ASSERT_EQ(4u, lists.getStructList8().size());
ASSERT_EQ(2u, lists.getStructList16().size());
ASSERT_EQ(3u, lists.getStructList32().size());
ASSERT_EQ(4u, lists.getStructList64().size());
ASSERT_EQ(2u, lists.getStructList128().size());
ASSERT_EQ(3u, lists.getStructList192().size());
ASSERT_EQ(4u, lists.getStructList0p().size());
ASSERT_EQ(2u, lists.getStructList1p().size());
ASSERT_EQ(3u, lists.getStructList8p().size());
ASSERT_EQ(4u, lists.getStructList16p().size());
ASSERT_EQ(2u, lists.getStructList32p().size());
ASSERT_EQ(3u, lists.getStructList64p().size());
ASSERT_EQ(4u, lists.getStructList128p().size());
ASSERT_EQ(2u, lists.getStructList192p().size());
lists.getVoidList().set(0, Void::VOID);
lists.getVoidList().set(1, Void::VOID);
lists.getBoolList().set(0, false);
lists.getBoolList().set(1, true);
lists.getBoolList().set(2, false);
lists.getUInt8List().set(0, 12u);
lists.getUInt8List().set(1, 34u);
lists.getUInt8List().set(2, 56u);
lists.getUInt8List().set(3, 78u);
lists.getUInt16List().set(0, 1234u);
lists.getUInt16List().set(1, 5678u);
lists.getUInt16List().set(2, 9012u);
lists.getUInt16List().set(3, 3456u);
lists.getUInt16List().set(4, 7890u);
lists.getUInt32List().set(0, 123456789u);
lists.getUInt32List().set(1, 234567890u);
lists.getUInt32List().set(2, 345678901u);
lists.getUInt32List().set(3, 456789012u);
lists.getUInt32List().set(4, 567890123u);
lists.getUInt32List().set(5, 678901234u);
for (uint i = 0; i < 7; i++) {
lists.getUInt64List().set(i, i + 1);
}
lists.getTextList().set(0, "foo");
lists.getTextList().set(1, "bar");
lists.getTextList().set(2, "baz");
lists.getTextList().set(3, "qux");
lists.getTextList().set(4, "quux");
lists.getTextList().set(5, "corge");
lists.getTextList().set(6, "grault");
lists.getTextList().set(7, "garply");
lists.getStructList0()[0].setF(Void::VOID);
lists.getStructList0()[1].setF(Void::VOID);
lists.getStructList8()[0].setF0(true);
lists.getStructList8()[0].setF1(false);
lists.getStructList8()[0].setF2(false);
lists.getStructList8()[1].setF0(false);
lists.getStructList8()[1].setF1(true);
lists.getStructList8()[1].setF2(false);
lists.getStructList8()[2].setF0(true);
lists.getStructList8()[2].setF1(true);
lists.getStructList8()[2].setF2(false);
lists.getStructList8()[3].setF0(false);
lists.getStructList8()[3].setF1(false);
lists.getStructList8()[3].setF2(true);
lists.getStructList16()[0].setF0(12u);
lists.getStructList16()[0].setF1(34u);
lists.getStructList16()[1].setF0(56u);
lists.getStructList16()[1].setF1(78u);
lists.getStructList32()[0].setF0(90u);
lists.getStructList32()[0].setF1(12345u);
lists.getStructList32()[1].setF0(67u);
lists.getStructList32()[1].setF1(8901u);
lists.getStructList32()[2].setF0(23u);
lists.getStructList32()[2].setF1(45678u);
lists.getStructList64()[0].setF0(90u);
lists.getStructList64()[0].setF1(123456789u);
lists.getStructList64()[1].setF0(12u);
lists.getStructList64()[1].setF1(345678901u);
lists.getStructList64()[2].setF0(234u);
lists.getStructList64()[2].setF1(567890123u);
lists.getStructList64()[3].setF0(45u);
lists.getStructList64()[3].setF1(678901234u);
lists.getStructList128()[0].setF0(56789012345678ull);
lists.getStructList128()[0].setF1(90123456789012ull);
lists.getStructList128()[1].setF0(34567890123456ull);
lists.getStructList128()[1].setF1(78901234567890ull);
lists.getStructList192()[0].setF0(1234567890123ull);
lists.getStructList192()[0].setF1(4567890123456ull);
lists.getStructList192()[0].setF2(7890123456789ull);
lists.getStructList192()[1].setF0( 123456789012ull);
lists.getStructList192()[1].setF1(3456789012345ull);
lists.getStructList192()[1].setF2(6789012345678ull);
lists.getStructList192()[2].setF0(9012345678901ull);
lists.getStructList192()[2].setF1(2345678901234ull);
lists.getStructList192()[2].setF2(5678901234567ull);
lists.getStructList0p()[0].setP0("foo");
lists.getStructList0p()[1].setP0("bar");
lists.getStructList0p()[2].setP0("baz");
lists.getStructList0p()[3].setP0("qux");
lists.getStructList8p()[0].getF().setF0(true);
lists.getStructList8p()[0].setP0("grault");
lists.getStructList8p()[1].setP0("garply");
lists.getStructList8p()[2].setP0("waldo");
lists.getStructList16p()[0].getF().setF0(123u);
lists.getStructList16p()[0].setP0("fred");
lists.getStructList16p()[0].setP1("plugh");
lists.getStructList16p()[1].setP0("xyzzy");
lists.getStructList16p()[1].setP1("thud");
lists.getStructList16p()[2].setP0("foobar");
lists.getStructList16p()[2].setP1("barbaz");
lists.getStructList16p()[3].setP0("bazqux");
lists.getStructList16p()[3].setP1("quxquux");
lists.getStructList32p()[0].getF().setF1(12345u);
lists.getStructList32p()[0].setP0("quuxcorge");
lists.getStructList32p()[0].setP1("corgegrault");
lists.getStructList32p()[1].setP0("graultgarply");
lists.getStructList32p()[1].setP1("garplywaldo");
lists.getStructList64p()[0].getF().setF1(123456789u);
lists.getStructList64p()[0].setP0("waldofred");
lists.getStructList64p()[0].setP1("fredplugh");
lists.getStructList64p()[1].setP0("plughxyzzy");
lists.getStructList64p()[1].setP1("xyzzythud");
lists.getStructList64p()[2].setP0("thudfoo");
lists.getStructList64p()[2].setP1("foofoo");
lists.getStructList128p()[0].getF().setF1(123456789012345ull);
lists.getStructList128p()[0].setP0("foobaz");
lists.getStructList128p()[0].setP1("fooqux");
lists.getStructList128p()[0].setP2("foocorge");
lists.getStructList128p()[1].setP0("barbaz");
lists.getStructList128p()[1].setP1("barqux");
lists.getStructList128p()[1].setP2("barcorge");
lists.getStructList128p()[2].setP0("bazbaz");
lists.getStructList128p()[2].setP1("bazqux");
lists.getStructList128p()[2].setP2("bazcorge");
lists.getStructList128p()[3].setP0("quxbaz");
lists.getStructList128p()[3].setP1("quxqux");
lists.getStructList128p()[3].setP2("quxcorge");
lists.getStructList192p()[0].getF().setF2(123456789012345ull);
lists.getStructList192p()[0].setP0("corgebaz");
lists.getStructList192p()[0].setP1("corgequx");
lists.getStructList192p()[0].setP2("corgecorge");
lists.getStructList192p()[1].setP0("graultbaz");
lists.getStructList192p()[1].setP1("graultqux");
lists.getStructList192p()[1].setP2("graultcorge");
lists.setData("12345");
}
{
auto sl = builder.initStructLists();
sl.initList0(2);
sl.initList1(2);
sl.initList8(2);
sl.initList16(2);
sl.initList32(2);
sl.initList64(2);
sl.initListP(2);
sl.getList0()[0].setF(Void::VOID);
sl.getList0()[1].setF(Void::VOID);
sl.getList1()[0].setF(true);
sl.getList1()[1].setF(false);
sl.getList8()[0].setF(123u);
sl.getList8()[1].setF(45u);
sl.getList16()[0].setF(12345u);
sl.getList16()[1].setF(6789u);
sl.getList32()[0].setF(123456789u);
sl.getList32()[1].setF(234567890u);
sl.getList64()[0].setF(1234567890123456u);
sl.getList64()[1].setF(2345678901234567u);
sl.getListP()[0].setF("foo");
sl.getListP()[1].setF("bar");
}
{
auto ll = builder.initListLists();
{
auto l = ll.initInt32ListList(3);
l.init(0, 3).copyFrom({1, 2, 3});
l.init(1, 2).copyFrom({4, 5});
l.init(2, 1).copyFrom({12341234});
}
{
auto l = ll.initTextListList(3);
l.init(0, 2).copyFrom({"foo", "bar"});
l.init(1, 1).copyFrom({"baz"});
l.init(2, 2).copyFrom({"qux", "corge"});
}
{
auto l = ll.initStructListList(2);
auto e = l.init(0, 2);
e[0].setInt32Field(123);
e[1].setInt32Field(456);
e = l.init(1, 1);
e[0].setInt32Field(789);
}
{
auto l = ll.initInt32InlineListList(2);
l[0].copyFrom({1, 2, 3, 4, 5, 6, 123456789});
l[1].copyFrom({987654321, 6, 5, 4, 3, 2, 1});
}
{
auto l = ll.initTextInlineListList(3);
l[0].copyFrom({"grault1", "grault2", "grault3", "grault4", "grault5"});
l[1].copyFrom({"garply1", "garply2", "garply3", "garply4", "garply5"});
l[2].copyFrom({"waldo1", "waldo2", "waldo3", "waldo4", "waldo5"});
}
{
auto l = ll.initStructInlineListList(3);
ASSERT_EQ(3u, l[0].size());
ASSERT_EQ(3u, l[1].size());
ASSERT_EQ(3u, l[2].size());
l[0][0].getF().setF1(123);
l[0][1].getF().setF1(456);
l[0][2].getF().setF1(789);
l[1][0].getF().setF1(321);
l[1][1].getF().setF1(654);
l[1][2].getF().setF1(987);
l[2][0].getF().setF1(111);
l[2][1].getF().setF1(222);
l[2][2].getF().setF1(333);
l[0][0].setP0("fred1");
l[0][1].setP0("fred2");
l[0][2].setP0("fred3");
l[1][0].setP0("plugh1");
l[1][1].setP0("plugh2");
l[1][2].setP0("plugh3");
l[2][0].setP0("thud1");
l[2][1].setP0("thud2");
l[2][2].setP0("thud3");
}
ll.setInlineDataList({"123456789", "234567890", "345678901", "456789012", "567890123"});
{
auto l = ll.initInt32InlineListListList(3);
l.init(0, 3);
l.init(1, 2);
l.init(2, 1);
ASSERT_EQ(2u, l[0][0].size());
ASSERT_EQ(2u, l[0][1].size());
ASSERT_EQ(2u, l[0][2].size());
ASSERT_EQ(2u, l[1][0].size());
ASSERT_EQ(2u, l[1][1].size());
ASSERT_EQ(2u, l[2][0].size());
l[0][0].copyFrom({1, 2});
l[0][1].copyFrom({3, 4});
l[0][2].copyFrom({5, 6});
l[1][0].copyFrom({7, 8});
l[1][1].copyFrom({9, 10});
l[2][0].copyFrom({1234567, 7654321});
}
{
auto l = ll.initTextInlineListListList(2);
l.init(0, 2);
l.init(1, 1);
ASSERT_EQ(5u, l[0][0].size());
ASSERT_EQ(5u, l[0][1].size());
ASSERT_EQ(5u, l[1][0].size());
l[0][0].copyFrom({"1", "2", "3", "4", "5"});
l[0][1].copyFrom({"foo", "bar", "baz", "qux", "corge"});
l[1][0].copyFrom({"z", "y", "x", "w", "v"});
}
{
auto l = ll.initStructInlineListListList(2);
l.init(0, 2);
l.init(1, 1);
ASSERT_EQ(3u, l[0][0].size());
ASSERT_EQ(3u, l[0][1].size());
ASSERT_EQ(3u, l[1][0].size());
l[0][0][0].getF().setF1(123);
l[0][0][1].getF().setF1(456);
l[0][0][2].getF().setF1(789);
l[0][1][0].getF().setF1(321);
l[0][1][1].getF().setF1(654);
l[0][1][2].getF().setF1(987);
l[1][0][0].getF().setF1(111);
l[1][0][1].getF().setF1(222);
l[1][0][2].getF().setF1(333);
l[0][0][0].setP0("fred1");
l[0][0][1].setP0("fred2");
l[0][0][2].setP0("fred3");
l[0][1][0].setP0("plugh1");
l[0][1][1].setP0("plugh2");
l[0][1][2].setP0("plugh3");
l[1][0][0].setP0("thud1");
l[1][0][1].setP0("thud2");
l[1][0][2].setP0("thud3");
}
{
auto l = ll.initInlineDataListList(2);
l.init(0, 3).copyFrom({"foo", "bar", "baz"});
l.init(1, 2).copyFrom({"123", "234"});
}
}
}
template <typename Reader>
void genericCheckInlineDefaults(Reader reader) {
{
auto normal = reader.getNormal();
EXPECT_TRUE(normal.getF8().getF0());
EXPECT_FALSE(normal.getF8().getF1());
EXPECT_TRUE(normal.getF8().getF2());
EXPECT_EQ(123u, normal.getF16().getF0());
EXPECT_EQ(45u, normal.getF16().getF1());
EXPECT_EQ(67u, normal.getF32().getF0());
EXPECT_EQ(8901u, normal.getF32().getF1());
EXPECT_EQ(234u, normal.getF64().getF0());
EXPECT_EQ(567890123u, normal.getF64().getF1());
EXPECT_EQ(1234567890123ull, normal.getF128().getF0());
EXPECT_EQ(4567890123456ull, normal.getF128().getF1());
EXPECT_EQ(7890123456789ull, normal.getF192().getF0());
EXPECT_EQ(2345678901234ull, normal.getF192().getF1());
EXPECT_EQ(5678901234567ull, normal.getF192().getF2());
EXPECT_TRUE(normal.getF8p().getF().getF0());
EXPECT_TRUE(normal.getF8p().getF().getF1());
EXPECT_FALSE(normal.getF8p().getF().getF2());
EXPECT_EQ(98u, normal.getF16p().getF().getF0());
EXPECT_EQ(76u, normal.getF16p().getF().getF1());
EXPECT_EQ(54u, normal.getF32p().getF().getF0());
EXPECT_EQ(32109u, normal.getF32p().getF().getF1());
EXPECT_EQ(87u, normal.getF64p().getF().getF0());
EXPECT_EQ(654321098u, normal.getF64p().getF().getF1());
EXPECT_EQ(7654321098765ull, normal.getF128p().getF().getF0());
EXPECT_EQ(4321098765432ull, normal.getF128p().getF().getF1());
EXPECT_EQ(1098765432109ull, normal.getF192p().getF().getF0());
EXPECT_EQ(8765432109876ull, normal.getF192p().getF().getF1());
EXPECT_EQ(5432109876543ull, normal.getF192p().getF().getF2());
EXPECT_EQ("foo", normal.getF0p().getP0());
EXPECT_EQ("baz", normal.getF8p().getP0());
EXPECT_EQ("qux", normal.getF16p().getP0());
EXPECT_EQ("quux", normal.getF16p().getP1());
EXPECT_EQ("corge", normal.getF32p().getP0());
EXPECT_EQ("grault", normal.getF32p().getP1());
EXPECT_EQ("garply", normal.getF64p().getP0());
EXPECT_EQ("waldo", normal.getF64p().getP1());
EXPECT_EQ("fred", normal.getF128p().getP0());
EXPECT_EQ("plugh", normal.getF128p().getP1());
EXPECT_EQ("xyzzy", normal.getF128p().getP2());
EXPECT_EQ("thud", normal.getF192p().getP0());
EXPECT_EQ("foobar", normal.getF192p().getP1());
EXPECT_EQ("barbaz", normal.getF192p().getP2());
}
{
auto unions = reader.getUnions();
ASSERT_EQ(TestInlineUnions::Union0::F32, unions.getUnion0().which());
EXPECT_EQ(67u, unions.getUnion0().getF32().getF0());
EXPECT_EQ(8901u, unions.getUnion0().getF32().getF1());
ASSERT_EQ(TestInlineUnions::Union1::F128, unions.getUnion1().which());
EXPECT_EQ(1234567890123ull, unions.getUnion1().getF128().getF0());
EXPECT_EQ(4567890123456ull, unions.getUnion1().getF128().getF1());
ASSERT_EQ(TestInlineUnions::Union3::F16P, unions.getUnion3().which());
EXPECT_EQ(98u, unions.getUnion3().getF16p().getF().getF0());
EXPECT_EQ(76u, unions.getUnion3().getF16p().getF().getF1());
EXPECT_EQ("qux", unions.getUnion3().getF16p().getP0());
EXPECT_EQ("quux", unions.getUnion3().getF16p().getP1());
}
{
auto lists = reader.getLists();
ASSERT_EQ(2u, lists.getVoidList().size());
ASSERT_EQ(3u, lists.getBoolList().size());
ASSERT_EQ(4u, lists.getUInt8List().size());
ASSERT_EQ(5u, lists.getUInt16List().size());
ASSERT_EQ(6u, lists.getUInt32List().size());
ASSERT_EQ(7u, lists.getUInt64List().size());
ASSERT_EQ(8u, lists.getTextList().size());
ASSERT_EQ(2u, lists.getStructList0().size());
ASSERT_EQ(3u, lists.getStructList1().size());
ASSERT_EQ(4u, lists.getStructList8().size());
ASSERT_EQ(2u, lists.getStructList16().size());
ASSERT_EQ(3u, lists.getStructList32().size());
ASSERT_EQ(4u, lists.getStructList64().size());
ASSERT_EQ(2u, lists.getStructList128().size());
ASSERT_EQ(3u, lists.getStructList192().size());
ASSERT_EQ(4u, lists.getStructList0p().size());
ASSERT_EQ(2u, lists.getStructList1p().size());
ASSERT_EQ(3u, lists.getStructList8p().size());
ASSERT_EQ(4u, lists.getStructList16p().size());
ASSERT_EQ(2u, lists.getStructList32p().size());
ASSERT_EQ(3u, lists.getStructList64p().size());
ASSERT_EQ(4u, lists.getStructList128p().size());
ASSERT_EQ(2u, lists.getStructList192p().size());
EXPECT_EQ(Void::VOID, lists.getVoidList()[0]);
EXPECT_EQ(Void::VOID, lists.getVoidList()[1]);
EXPECT_FALSE(lists.getBoolList()[0]);
EXPECT_TRUE(lists.getBoolList()[1]);
EXPECT_FALSE(lists.getBoolList()[2]);
EXPECT_EQ(12u, lists.getUInt8List()[0]);
EXPECT_EQ(34u, lists.getUInt8List()[1]);
EXPECT_EQ(56u, lists.getUInt8List()[2]);
EXPECT_EQ(78u, lists.getUInt8List()[3]);
EXPECT_EQ(1234u, lists.getUInt16List()[0]);
EXPECT_EQ(5678u, lists.getUInt16List()[1]);
EXPECT_EQ(9012u, lists.getUInt16List()[2]);
EXPECT_EQ(3456u, lists.getUInt16List()[3]);
EXPECT_EQ(7890u, lists.getUInt16List()[4]);
EXPECT_EQ(123456789u, lists.getUInt32List()[0]);
EXPECT_EQ(234567890u, lists.getUInt32List()[1]);
EXPECT_EQ(345678901u, lists.getUInt32List()[2]);
EXPECT_EQ(456789012u, lists.getUInt32List()[3]);
EXPECT_EQ(567890123u, lists.getUInt32List()[4]);
EXPECT_EQ(678901234u, lists.getUInt32List()[5]);
for (uint i = 0; i < 7; i++) {
EXPECT_EQ(i + 1, lists.getUInt64List()[i]);
}
EXPECT_EQ("foo", lists.getTextList()[0]);
EXPECT_EQ("bar", lists.getTextList()[1]);
EXPECT_EQ("baz", lists.getTextList()[2]);
EXPECT_EQ("qux", lists.getTextList()[3]);
EXPECT_EQ("quux", lists.getTextList()[4]);
EXPECT_EQ("corge", lists.getTextList()[5]);
EXPECT_EQ("grault", lists.getTextList()[6]);
EXPECT_EQ("garply", lists.getTextList()[7]);
EXPECT_EQ(Void::VOID, lists.getStructList0()[0].getF());
EXPECT_EQ(Void::VOID, lists.getStructList0()[1].getF());
EXPECT_TRUE (lists.getStructList8()[0].getF0());
EXPECT_FALSE(lists.getStructList8()[0].getF1());
EXPECT_FALSE(lists.getStructList8()[0].getF2());
EXPECT_FALSE(lists.getStructList8()[1].getF0());
EXPECT_TRUE (lists.getStructList8()[1].getF1());
EXPECT_FALSE(lists.getStructList8()[1].getF2());
EXPECT_TRUE (lists.getStructList8()[2].getF0());
EXPECT_TRUE (lists.getStructList8()[2].getF1());
EXPECT_FALSE(lists.getStructList8()[2].getF2());
EXPECT_FALSE(lists.getStructList8()[3].getF0());
EXPECT_FALSE(lists.getStructList8()[3].getF1());
EXPECT_TRUE (lists.getStructList8()[3].getF2());
EXPECT_EQ(12u, lists.getStructList16()[0].getF0());
EXPECT_EQ(34u, lists.getStructList16()[0].getF1());
EXPECT_EQ(56u, lists.getStructList16()[1].getF0());
EXPECT_EQ(78u, lists.getStructList16()[1].getF1());
EXPECT_EQ(90u, lists.getStructList32()[0].getF0());
EXPECT_EQ(12345u, lists.getStructList32()[0].getF1());
EXPECT_EQ(67u, lists.getStructList32()[1].getF0());
EXPECT_EQ(8901u, lists.getStructList32()[1].getF1());
EXPECT_EQ(23u, lists.getStructList32()[2].getF0());
EXPECT_EQ(45678u, lists.getStructList32()[2].getF1());
EXPECT_EQ(90u, lists.getStructList64()[0].getF0());
EXPECT_EQ(123456789u, lists.getStructList64()[0].getF1());
EXPECT_EQ(12u, lists.getStructList64()[1].getF0());
EXPECT_EQ(345678901u, lists.getStructList64()[1].getF1());
EXPECT_EQ(234u, lists.getStructList64()[2].getF0());
EXPECT_EQ(567890123u, lists.getStructList64()[2].getF1());
EXPECT_EQ(45u, lists.getStructList64()[3].getF0());
EXPECT_EQ(678901234u, lists.getStructList64()[3].getF1());
EXPECT_EQ(56789012345678ull, lists.getStructList128()[0].getF0());
EXPECT_EQ(90123456789012ull, lists.getStructList128()[0].getF1());
EXPECT_EQ(34567890123456ull, lists.getStructList128()[1].getF0());
EXPECT_EQ(78901234567890ull, lists.getStructList128()[1].getF1());
EXPECT_EQ(1234567890123ull, lists.getStructList192()[0].getF0());
EXPECT_EQ(4567890123456ull, lists.getStructList192()[0].getF1());
EXPECT_EQ(7890123456789ull, lists.getStructList192()[0].getF2());
EXPECT_EQ( 123456789012ull, lists.getStructList192()[1].getF0());
EXPECT_EQ(3456789012345ull, lists.getStructList192()[1].getF1());
EXPECT_EQ(6789012345678ull, lists.getStructList192()[1].getF2());
EXPECT_EQ(9012345678901ull, lists.getStructList192()[2].getF0());
EXPECT_EQ(2345678901234ull, lists.getStructList192()[2].getF1());
EXPECT_EQ(5678901234567ull, lists.getStructList192()[2].getF2());
EXPECT_EQ("foo", lists.getStructList0p()[0].getP0());
EXPECT_EQ("bar", lists.getStructList0p()[1].getP0());
EXPECT_EQ("baz", lists.getStructList0p()[2].getP0());
EXPECT_EQ("qux", lists.getStructList0p()[3].getP0());
EXPECT_TRUE(lists.getStructList8p()[0].getF().getF0());
EXPECT_EQ("grault", lists.getStructList8p()[0].getP0());
EXPECT_EQ("garply", lists.getStructList8p()[1].getP0());
EXPECT_EQ("waldo", lists.getStructList8p()[2].getP0());
EXPECT_EQ(123u, lists.getStructList16p()[0].getF().getF0());
EXPECT_EQ("fred", lists.getStructList16p()[0].getP0());
EXPECT_EQ("plugh", lists.getStructList16p()[0].getP1());
EXPECT_EQ("xyzzy", lists.getStructList16p()[1].getP0());
EXPECT_EQ("thud", lists.getStructList16p()[1].getP1());
EXPECT_EQ("foobar", lists.getStructList16p()[2].getP0());
EXPECT_EQ("barbaz", lists.getStructList16p()[2].getP1());
EXPECT_EQ("bazqux", lists.getStructList16p()[3].getP0());
EXPECT_EQ("quxquux", lists.getStructList16p()[3].getP1());
EXPECT_EQ(12345u, lists.getStructList32p()[0].getF().getF1());
EXPECT_EQ("quuxcorge", lists.getStructList32p()[0].getP0());
EXPECT_EQ("corgegrault", lists.getStructList32p()[0].getP1());
EXPECT_EQ("graultgarply", lists.getStructList32p()[1].getP0());
EXPECT_EQ("garplywaldo", lists.getStructList32p()[1].getP1());
EXPECT_EQ(123456789u, lists.getStructList64p()[0].getF().getF1());
EXPECT_EQ("waldofred", lists.getStructList64p()[0].getP0());
EXPECT_EQ("fredplugh", lists.getStructList64p()[0].getP1());
EXPECT_EQ("plughxyzzy", lists.getStructList64p()[1].getP0());
EXPECT_EQ("xyzzythud", lists.getStructList64p()[1].getP1());
EXPECT_EQ("thudfoo", lists.getStructList64p()[2].getP0());
EXPECT_EQ("foofoo", lists.getStructList64p()[2].getP1());
EXPECT_EQ(123456789012345ull, lists.getStructList128p()[0].getF().getF1());
EXPECT_EQ("foobaz", lists.getStructList128p()[0].getP0());
EXPECT_EQ("fooqux", lists.getStructList128p()[0].getP1());
EXPECT_EQ("foocorge", lists.getStructList128p()[0].getP2());
EXPECT_EQ("barbaz", lists.getStructList128p()[1].getP0());
EXPECT_EQ("barqux", lists.getStructList128p()[1].getP1());
EXPECT_EQ("barcorge", lists.getStructList128p()[1].getP2());
EXPECT_EQ("bazbaz", lists.getStructList128p()[2].getP0());
EXPECT_EQ("bazqux", lists.getStructList128p()[2].getP1());
EXPECT_EQ("bazcorge", lists.getStructList128p()[2].getP2());
EXPECT_EQ("quxbaz", lists.getStructList128p()[3].getP0());
EXPECT_EQ("quxqux", lists.getStructList128p()[3].getP1());
EXPECT_EQ("quxcorge", lists.getStructList128p()[3].getP2());
EXPECT_EQ(123456789012345ull, lists.getStructList192p()[0].getF().getF2());
EXPECT_EQ("corgebaz", lists.getStructList192p()[0].getP0());
EXPECT_EQ("corgequx", lists.getStructList192p()[0].getP1());
EXPECT_EQ("corgecorge", lists.getStructList192p()[0].getP2());
EXPECT_EQ("graultbaz", lists.getStructList192p()[1].getP0());
EXPECT_EQ("graultqux", lists.getStructList192p()[1].getP1());
EXPECT_EQ("graultcorge", lists.getStructList192p()[1].getP2());
EXPECT_EQ("12345", lists.getData());
}
{
auto sl = reader.getStructLists();
ASSERT_EQ(2u, sl.getList0().size());
ASSERT_EQ(2u, sl.getList1().size());
ASSERT_EQ(2u, sl.getList8().size());
ASSERT_EQ(2u, sl.getList16().size());
ASSERT_EQ(2u, sl.getList32().size());
ASSERT_EQ(2u, sl.getList64().size());
ASSERT_EQ(2u, sl.getListP().size());
EXPECT_EQ(Void::VOID, sl.getList0()[0].getF());
EXPECT_EQ(Void::VOID, sl.getList0()[1].getF());
EXPECT_TRUE(sl.getList1()[0].getF());
EXPECT_FALSE(sl.getList1()[1].getF());
EXPECT_EQ(123u, sl.getList8()[0].getF());
EXPECT_EQ(45u, sl.getList8()[1].getF());
EXPECT_EQ(12345u, sl.getList16()[0].getF());
EXPECT_EQ(6789u, sl.getList16()[1].getF());
EXPECT_EQ(123456789u, sl.getList32()[0].getF());
EXPECT_EQ(234567890u, sl.getList32()[1].getF());
EXPECT_EQ(1234567890123456u, sl.getList64()[0].getF());
EXPECT_EQ(2345678901234567u, sl.getList64()[1].getF());
EXPECT_EQ("foo", sl.getListP()[0].getF());
EXPECT_EQ("bar", sl.getListP()[1].getF());
}
{
auto ll = reader.getListLists();
{
auto l = ll.getInt32ListList();
ASSERT_EQ(3u, l.size());
checkList(l[0], {1, 2, 3});
checkList(l[1], {4, 5});
checkList(l[2], {12341234});
}
{
auto l = ll.getTextListList();
ASSERT_EQ(3u, l.size());
checkList(l[0], {"foo", "bar"});
checkList(l[1], {"baz"});
checkList(l[2], {"qux", "corge"});
}
{
auto l = ll.getStructListList();
ASSERT_EQ(2u, l.size());
auto e = l[0];
ASSERT_EQ(2u, e.size());
EXPECT_EQ(123, e[0].getInt32Field());
EXPECT_EQ(456, e[1].getInt32Field());
e = l[1];
ASSERT_EQ(1u, e.size());
EXPECT_EQ(789, e[0].getInt32Field());
}
{
auto l = ll.getInt32InlineListList();
ASSERT_EQ(2u, l.size());
checkList(l[0], {1, 2, 3, 4, 5, 6, 123456789});
checkList(l[1], {987654321, 6, 5, 4, 3, 2, 1});
}
{
auto l = ll.getTextInlineListList();
ASSERT_EQ(3u, l.size());
checkList(l[0], {"grault1", "grault2", "grault3", "grault4", "grault5"});
checkList(l[1], {"garply1", "garply2", "garply3", "garply4", "garply5"});
checkList(l[2], {"waldo1", "waldo2", "waldo3", "waldo4", "waldo5"});
}
{
auto l = ll.getStructInlineListList();
ASSERT_EQ(3u, l.size());
ASSERT_EQ(3u, l[0].size());
ASSERT_EQ(3u, l[1].size());
ASSERT_EQ(3u, l[2].size());
EXPECT_EQ(123, l[0][0].getF().getF1());
EXPECT_EQ(456, l[0][1].getF().getF1());
EXPECT_EQ(789, l[0][2].getF().getF1());
EXPECT_EQ(321, l[1][0].getF().getF1());
EXPECT_EQ(654, l[1][1].getF().getF1());
EXPECT_EQ(987, l[1][2].getF().getF1());
EXPECT_EQ(111, l[2][0].getF().getF1());
EXPECT_EQ(222, l[2][1].getF().getF1());
EXPECT_EQ(333, l[2][2].getF().getF1());
EXPECT_EQ("fred1", l[0][0].getP0());
EXPECT_EQ("fred2", l[0][1].getP0());
EXPECT_EQ("fred3", l[0][2].getP0());
EXPECT_EQ("plugh1", l[1][0].getP0());
EXPECT_EQ("plugh2", l[1][1].getP0());
EXPECT_EQ("plugh3", l[1][2].getP0());
EXPECT_EQ("thud1", l[2][0].getP0());
EXPECT_EQ("thud2", l[2][1].getP0());
EXPECT_EQ("thud3", l[2][2].getP0());
}
checkList(ll.getInlineDataList(),
{"123456789", "234567890", "345678901", "456789012", "567890123"});
{
auto l = ll.getInt32InlineListListList();
ASSERT_EQ(3u, l.size());
ASSERT_EQ(3u, l[0].size());
ASSERT_EQ(2u, l[1].size());
ASSERT_EQ(1u, l[2].size());
ASSERT_EQ(2u, l[0][0].size());
ASSERT_EQ(2u, l[0][1].size());
ASSERT_EQ(2u, l[0][2].size());
ASSERT_EQ(2u, l[1][0].size());
ASSERT_EQ(2u, l[1][1].size());
ASSERT_EQ(2u, l[2][0].size());
checkList(l[0][0], {1, 2});
checkList(l[0][1], {3, 4});
checkList(l[0][2], {5, 6});
checkList(l[1][0], {7, 8});
checkList(l[1][1], {9, 10});
checkList(l[2][0], {1234567, 7654321});
}
{
auto l = ll.getTextInlineListListList();
ASSERT_EQ(2u, l.size());
ASSERT_EQ(2u, l[0].size());
ASSERT_EQ(1u, l[1].size());
ASSERT_EQ(5u, l[0][0].size());
ASSERT_EQ(5u, l[0][1].size());
ASSERT_EQ(5u, l[1][0].size());
checkList(l[0][0], {"1", "2", "3", "4", "5"});
checkList(l[0][1], {"foo", "bar", "baz", "qux", "corge"});
checkList(l[1][0], {"z", "y", "x", "w", "v"});
}
{
auto l = ll.getStructInlineListListList();
ASSERT_EQ(2u, l.size());
ASSERT_EQ(2u, l[0].size());
ASSERT_EQ(1u, l[1].size());
ASSERT_EQ(3u, l[0][0].size());
ASSERT_EQ(3u, l[0][1].size());
ASSERT_EQ(3u, l[1][0].size());
EXPECT_EQ(123, l[0][0][0].getF().getF1());
EXPECT_EQ(456, l[0][0][1].getF().getF1());
EXPECT_EQ(789, l[0][0][2].getF().getF1());
EXPECT_EQ(321, l[0][1][0].getF().getF1());
EXPECT_EQ(654, l[0][1][1].getF().getF1());
EXPECT_EQ(987, l[0][1][2].getF().getF1());
EXPECT_EQ(111, l[1][0][0].getF().getF1());
EXPECT_EQ(222, l[1][0][1].getF().getF1());
EXPECT_EQ(333, l[1][0][2].getF().getF1());
EXPECT_EQ("fred1", l[0][0][0].getP0());
EXPECT_EQ("fred2", l[0][0][1].getP0());
EXPECT_EQ("fred3", l[0][0][2].getP0());
EXPECT_EQ("plugh1", l[0][1][0].getP0());
EXPECT_EQ("plugh2", l[0][1][1].getP0());
EXPECT_EQ("plugh3", l[0][1][2].getP0());
EXPECT_EQ("thud1", l[1][0][0].getP0());
EXPECT_EQ("thud2", l[1][0][1].getP0());
EXPECT_EQ("thud3", l[1][0][2].getP0());
}
{
auto l = ll.getInlineDataListList();
ASSERT_EQ(2u, l.size());
checkList(l[0], {"foo", "bar", "baz"});
checkList(l[1], {"123", "234"});
}
}
}
} // namespace } // namespace
void initTestMessage(TestAllTypes::Builder builder) { genericInitTestMessage(builder); } void initTestMessage(TestAllTypes::Builder builder) { genericInitTestMessage(builder); }
void initTestMessage(TestDefaults::Builder builder) { genericInitTestMessage(builder); } void initTestMessage(TestDefaults::Builder builder) { genericInitTestMessage(builder); }
void initTestMessage(TestInlineDefaults::Builder builder) { genericInitInlineDefaults(builder); }
void checkTestMessage(TestAllTypes::Builder builder) { genericCheckTestMessage(builder); } void checkTestMessage(TestAllTypes::Builder builder) { genericCheckTestMessage(builder); }
void checkTestMessage(TestDefaults::Builder builder) { genericCheckTestMessage(builder); } void checkTestMessage(TestDefaults::Builder builder) { genericCheckTestMessage(builder); }
void checkTestMessage(TestInlineDefaults::Builder builder) { genericCheckInlineDefaults(builder); }
void checkTestMessage(TestAllTypes::Reader reader) { genericCheckTestMessage(reader); } void checkTestMessage(TestAllTypes::Reader reader) { genericCheckTestMessage(reader); }
void checkTestMessage(TestDefaults::Reader reader) { genericCheckTestMessage(reader); } void checkTestMessage(TestDefaults::Reader reader) { genericCheckTestMessage(reader); }
void checkTestMessage(TestInlineDefaults::Reader reader) { genericCheckInlineDefaults(reader); }
void checkTestMessageAllZero(TestAllTypes::Builder builder) { void checkTestMessageAllZero(TestAllTypes::Builder builder) {
genericCheckTestMessageAllZero(builder); genericCheckTestMessageAllZero(builder);
......
...@@ -48,30 +48,35 @@ inline std::ostream& operator<<(std::ostream& os, Void) { ...@@ -48,30 +48,35 @@ inline std::ostream& operator<<(std::ostream& os, Void) {
namespace internal { namespace internal {
// Explicitly import each of these to make sure they're really located in capnproto::test and not, namespace test = capnproto_test::capnproto::test;
// say, the global namespace.
using ::capnproto::test::TestAllTypes;
using ::capnproto::test::TestDefaults;
using ::capnproto::test::TestEnum;
using ::capnproto::test::TestUnion;
using ::capnproto::test::TestUnionDefaults;
using ::capnproto::test::TestNestedTypes;
using ::capnproto::test::TestUsing;
using ::capnproto::test::TestInlineLayout;
using ::capnproto::test::TestInlineUnions;
using ::capnproto::test::TestInlineDefaults;
void initTestMessage(test::TestAllTypes::Builder builder); // We don't use "using namespace" to pull these in because then things would still compile
void initTestMessage(test::TestDefaults::Builder builder); // correctly if they were generated in the global namespace.
using ::capnproto_test::capnproto::test::TestAllTypes;
using ::capnproto_test::capnproto::test::TestDefaults;
using ::capnproto_test::capnproto::test::TestEnum;
using ::capnproto_test::capnproto::test::TestUnion;
using ::capnproto_test::capnproto::test::TestUnionDefaults;
using ::capnproto_test::capnproto::test::TestNestedTypes;
using ::capnproto_test::capnproto::test::TestUsing;
using ::capnproto_test::capnproto::test::TestInlineLayout;
using ::capnproto_test::capnproto::test::TestInlineUnions;
using ::capnproto_test::capnproto::test::TestInlineDefaults;
void checkTestMessage(test::TestAllTypes::Builder builder); void initTestMessage(TestAllTypes::Builder builder);
void checkTestMessage(test::TestDefaults::Builder builder); void initTestMessage(TestDefaults::Builder builder);
void initTestMessage(TestInlineDefaults::Builder builder);
void checkTestMessage(test::TestAllTypes::Reader reader); void checkTestMessage(TestAllTypes::Builder builder);
void checkTestMessage(test::TestDefaults::Reader reader); void checkTestMessage(TestDefaults::Builder builder);
void checkTestMessage(TestInlineDefaults::Builder builder);
void checkTestMessageAllZero(test::TestAllTypes::Builder builder); void checkTestMessage(TestAllTypes::Reader reader);
void checkTestMessageAllZero(test::TestAllTypes::Reader reader); void checkTestMessage(TestDefaults::Reader reader);
void checkTestMessage(TestInlineDefaults::Reader reader);
void checkTestMessageAllZero(TestAllTypes::Builder builder);
void checkTestMessageAllZero(TestAllTypes::Reader reader);
} // namespace internal } // namespace internal
} // namespace capnproto } // namespace capnproto
......
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
using Cxx = import "c++.capnp"; using Cxx = import "c++.capnp";
$Cxx.namespace("capnproto::test"); # Use a namespace likely to cause trouble if the generated code doesn't use fully-qualified
# names for stuff in the capnproto namespace.
$Cxx.namespace("capnproto_test::capnproto::test");
enum TestEnum { enum TestEnum {
foo @0; foo @0;
...@@ -406,6 +408,8 @@ struct TestInlineLists { ...@@ -406,6 +408,8 @@ struct TestInlineLists {
structList64p @20 : InlineList(TestInline64p, 3); structList64p @20 : InlineList(TestInline64p, 3);
structList128p @21 : InlineList(TestInline128p, 4); structList128p @21 : InlineList(TestInline128p, 4);
structList192p @22 : InlineList(TestInline192p, 2); structList192p @22 : InlineList(TestInline192p, 2);
data @23 :InlineData(5);
} }
struct TestStructLists { struct TestStructLists {
...@@ -428,6 +432,22 @@ struct TestStructLists { ...@@ -428,6 +432,22 @@ struct TestStructLists {
listP @6 :List(StructP); listP @6 :List(StructP);
} }
struct TestListLists {
int32ListList @0 :List(List(Int32));
textListList @1 :List(List(Text));
structListList @2 :List(List(TestAllTypes));
int32InlineListList @3 :List(InlineList(Int32, 7));
textInlineListList @4 :List(InlineList(Text, 5));
structInlineListList @5 :List(InlineList(TestInline32p, 3));
inlineDataList @6 :List(InlineData(9));
int32InlineListListList @7 :List(List(InlineList(Int32, 2)));
textInlineListListList @8 :List(List(InlineList(Text, 5)));
structInlineListListList @9 :List(List(InlineList(TestInline32p, 3)));
inlineDataListList @10 :List(List(InlineData(3)));
}
struct TestInlineDefaults { struct TestInlineDefaults {
normal @0 :TestInlineLayout = ( normal @0 :TestInlineLayout = (
f0 = (f = void), f0 = (f = void),
...@@ -497,7 +517,9 @@ struct TestInlineDefaults { ...@@ -497,7 +517,9 @@ struct TestInlineDefaults {
(p0 = "quxbaz", p1 = "quxqux", p2 = "quxcorge")], (p0 = "quxbaz", p1 = "quxqux", p2 = "quxcorge")],
structList192p = [(f = (f2 = 123456789012345), structList192p = [(f = (f2 = 123456789012345),
p0 = "corgebaz", p1 = "corgequx", p2 = "corgecorge"), p0 = "corgebaz", p1 = "corgequx", p2 = "corgecorge"),
(p0 = "graultbaz", p1 = "graultqux", p2 = "graultcorge")]); (p0 = "graultbaz", p1 = "graultqux", p2 = "graultcorge")],
data = "12345");
structLists @3 :TestStructLists = ( structLists @3 :TestStructLists = (
list0 = [(f = void), (f = void)], list0 = [(f = void), (f = void)],
...@@ -507,4 +529,30 @@ struct TestInlineDefaults { ...@@ -507,4 +529,30 @@ struct TestInlineDefaults {
list32 = [(f = 123456789), (f = 234567890)], list32 = [(f = 123456789), (f = 234567890)],
list64 = [(f = 1234567890123456), (f = 2345678901234567)], list64 = [(f = 1234567890123456), (f = 2345678901234567)],
listP = [(f = "foo"), (f = "bar")]); listP = [(f = "foo"), (f = "bar")]);
listLists @4 :TestListLists = (
int32ListList = [[1, 2, 3], [4, 5], [12341234]],
textListList = [["foo", "bar"], ["baz"], ["qux", "corge"]],
structListList = [[(int32Field = 123), (int32Field = 456)], [(int32Field = 789)]],
int32InlineListList = [[1, 2, 3, 4, 5, 6, 123456789], [987654321, 6, 5, 4, 3, 2, 1]],
textInlineListList = [["grault1", "grault2", "grault3", "grault4", "grault5"],
["garply1", "garply2", "garply3", "garply4", "garply5"],
["waldo1", "waldo2", "waldo3", "waldo4", "waldo5"]],
structInlineListList =
[[(f=(f1=123), p0="fred1"), (f=(f1=456), p0="fred2"), (f=(f1=789), p0="fred3")],
[(f=(f1=321), p0="plugh1"), (f=(f1=654), p0="plugh2"), (f=(f1=987), p0="plugh3")],
[(f=(f1=111), p0="thud1"), (f=(f1=222), p0="thud2"), (f=(f1=333), p0="thud3")]],
inlineDataList = ["123456789", "234567890", "345678901", "456789012", "567890123"],
int32InlineListListList = [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10]], [[1234567,7654321]]],
textInlineListListList = [[["1", "2", "3", "4", "5"],
["foo", "bar", "baz", "qux", "corge"]],
[["z", "y", "x", "w", "v"]]],
structInlineListListList =
[[[(f=(f1=123), p0="fred1"), (f=(f1=456), p0="fred2"), (f=(f1=789), p0="fred3")],
[(f=(f1=321), p0="plugh1"), (f=(f1=654), p0="plugh2"), (f=(f1=987), p0="plugh3")]],
[[(f=(f1=111), p0="thud1"), (f=(f1=222), p0="thud2"), (f=(f1=333), p0="thud3")]]],
inlineDataListList = [["foo", "bar", "baz"], ["123", "234"]]);
} }
...@@ -47,6 +47,7 @@ STRINGIFY_INT(long, "%ld"); ...@@ -47,6 +47,7 @@ STRINGIFY_INT(long, "%ld");
STRINGIFY_INT(unsigned long, "%lu"); STRINGIFY_INT(unsigned long, "%lu");
STRINGIFY_INT(long long, "%lld"); STRINGIFY_INT(long long, "%lld");
STRINGIFY_INT(unsigned long long, "%llu"); STRINGIFY_INT(unsigned long long, "%llu");
STRINGIFY_INT(const void*, "%p");
#undef STRINGIFY_INT #undef STRINGIFY_INT
......
...@@ -125,7 +125,7 @@ template <typename Element> ...@@ -125,7 +125,7 @@ template <typename Element>
Element* fill(Element* ptr) { return ptr; } Element* fill(Element* ptr) { return ptr; }
template <typename Element, typename First, typename... Rest> template <typename Element, typename First, typename... Rest>
Element* fill(Element* __restrict__ target, First& first, Rest&&... rest) { Element* fill(Element* __restrict__ target, const First& first, Rest&&... rest) {
auto i = first.begin(); auto i = first.begin();
auto end = first.end(); auto end = first.end();
while (i != end) { while (i != end) {
...@@ -134,16 +134,6 @@ Element* fill(Element* __restrict__ target, First& first, Rest&&... rest) { ...@@ -134,16 +134,6 @@ Element* fill(Element* __restrict__ target, First& first, Rest&&... rest) {
return fill(target, std::forward<Rest>(rest)...); return fill(target, std::forward<Rest>(rest)...);
} }
template <typename Element, typename First, typename... Rest>
Element* fill(Element* __restrict__ target, First&& first, Rest&&... rest) {
auto i = first.begin();
auto end = first.end();
while (i != end) {
*target++ = std::move(*i++);
}
return fill(target, std::forward<Rest>(rest)...);
}
template <typename Element, typename... Params> template <typename Element, typename... Params>
Array<Element> concat(Params&&... params) { Array<Element> concat(Params&&... params) {
// Concatenate a bunch of containers into a single Array. The containers can be anything that // Concatenate a bunch of containers into a single Array. The containers can be anything that
...@@ -196,6 +186,10 @@ struct Stringifier { ...@@ -196,6 +186,10 @@ struct Stringifier {
CappedArray<char, sizeof(unsigned long long) * 4> operator*(unsigned long long i) const; CappedArray<char, sizeof(unsigned long long) * 4> operator*(unsigned long long i) const;
CappedArray<char, 24> operator*(float f) const; CappedArray<char, 24> operator*(float f) const;
CappedArray<char, 32> operator*(double f) const; CappedArray<char, 32> operator*(double f) const;
CappedArray<char, sizeof(const void*) * 4> operator*(const void* s) const;
template <typename T>
Array<char> operator*(ArrayPtr<T> arr) const;
}; };
static constexpr Stringifier STR; static constexpr Stringifier STR;
...@@ -210,6 +204,34 @@ Array<char> str(Params&&... params) { ...@@ -210,6 +204,34 @@ Array<char> str(Params&&... params) {
return concat<char>(STR * std::forward<Params>(params)...); return concat<char>(STR * std::forward<Params>(params)...);
} }
template <typename T>
Array<char> strArray(ArrayPtr<T> arr, const char* delim) {
size_t delimLen = strlen(delim);
decltype(STR * arr[0]) pieces[arr.size()];
size_t size = 0;
for (size_t i = 0; i < arr.size(); i++) {
if (i > 0) size += delimLen;
pieces[i] = STR * arr[i];
size += pieces[i].size();
}
Array<char> result = newArray<char>(size);
char* pos = result.begin();
for (size_t i = 0; i < arr.size(); i++) {
if (i > 0) {
memcpy(pos, delim, delimLen);
pos += delimLen;
}
pos = fill(pos, pieces[i]);
}
return result;
}
template <typename T>
inline Array<char> Stringifier::operator*(ArrayPtr<T> arr) const {
return strArray(arr, ", ");
}
} // namespace capnproto } // namespace capnproto
#endif // CAPNPROTO_UTIL_H_ #endif // CAPNPROTO_UTIL_H_
...@@ -164,6 +164,7 @@ builtinTypeMap = Map.fromList ...@@ -164,6 +164,7 @@ builtinTypeMap = Map.fromList
[("List", DescBuiltinList), [("List", DescBuiltinList),
("Inline", DescBuiltinInline), ("Inline", DescBuiltinInline),
("InlineList", DescBuiltinInlineList), ("InlineList", DescBuiltinInlineList),
("InlineData", DescBuiltinInlineData),
("id", DescBuiltinId)]) ("id", DescBuiltinId)])
------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------
...@@ -255,6 +256,12 @@ compileValue pos (InlineListType t s) (ListFieldValue l) = do ...@@ -255,6 +256,12 @@ compileValue pos (InlineListType t s) (ListFieldValue l) = do
makeError pos $ printf "Fixed-size list must have exactly %d elements." s makeError pos $ printf "Fixed-size list must have exactly %d elements." s
return $ ListDesc elements return $ ListDesc elements
compileValue pos (InlineDataType s) (StringFieldValue x) = let
bytes = map (fromIntegral . fromEnum) x
in if List.genericLength bytes == s
then succeed $ DataDesc bytes
else makeError pos $ printf "Fixed-size data must have exactly %d bytes." s
compileValue pos (BuiltinType BuiltinVoid) _ = makeError pos "Void fields cannot have values." compileValue pos (BuiltinType BuiltinVoid) _ = makeError pos "Void fields cannot have values."
compileValue pos (BuiltinType BuiltinBool) _ = makeExpectError pos "boolean" compileValue pos (BuiltinType BuiltinBool) _ = makeExpectError pos "boolean"
compileValue pos (BuiltinType BuiltinInt8) _ = makeExpectError pos "integer" compileValue pos (BuiltinType BuiltinInt8) _ = makeExpectError pos "integer"
...@@ -275,6 +282,7 @@ compileValue pos (StructType _) _ = makeExpectError pos "parenthesized list of f ...@@ -275,6 +282,7 @@ compileValue pos (StructType _) _ = makeExpectError pos "parenthesized list of f
compileValue pos (InterfaceType _) _ = makeError pos "Interfaces can't have default values." compileValue pos (InterfaceType _) _ = makeError pos "Interfaces can't have default values."
compileValue pos (ListType _) _ = makeExpectError pos "list" compileValue pos (ListType _) _ = makeExpectError pos "list"
compileValue pos (InlineListType _ _) _ = makeExpectError pos "list" compileValue pos (InlineListType _ _) _ = makeExpectError pos "list"
compileValue pos (InlineDataType _) _ = makeExpectError pos "string"
descAsType _ (DescEnum desc) = succeed (EnumType desc) descAsType _ (DescEnum desc) = succeed (EnumType desc)
descAsType _ (DescStruct desc) = succeed (StructType desc) descAsType _ (DescStruct desc) = succeed (StructType desc)
...@@ -286,7 +294,9 @@ descAsType name DescBuiltinList = makeError (declNamePos name) message where ...@@ -286,7 +294,9 @@ descAsType name DescBuiltinList = makeError (declNamePos name) message where
descAsType name DescBuiltinInline = makeError (declNamePos name) message where descAsType name DescBuiltinInline = makeError (declNamePos name) message where
message = printf "'Inline' requires exactly one type parameter." (declNameString name) message = printf "'Inline' requires exactly one type parameter." (declNameString name)
descAsType name DescBuiltinInlineList = makeError (declNamePos name) message where descAsType name DescBuiltinInlineList = makeError (declNamePos name) message where
message = printf "'InlineList' requires exactly one type parameter." (declNameString name) message = printf "'InlineList' requires exactly two type parameters." (declNameString name)
descAsType name DescBuiltinInlineData = makeError (declNamePos name) message where
message = printf "'InlineData' requires exactly one type parameter." (declNameString name)
descAsType name _ = makeError (declNamePos name) message where descAsType name _ = makeError (declNamePos name) message where
message = printf "'%s' is not a type." (declNameString name) message = printf "'%s' is not a type." (declNameString name)
...@@ -328,9 +338,15 @@ compileType scope (TypeExpression n params) = do ...@@ -328,9 +338,15 @@ compileType scope (TypeExpression n params) = do
(structName s) (structName s)
InlineListType _ _ -> makeError (declNamePos n) InlineListType _ _ -> makeError (declNamePos n)
"InlineList of InlineList not currently supported." "InlineList of InlineList not currently supported."
InlineDataType _ -> makeError (declNamePos n)
"InlineList of InlineData not currently supported."
_ -> return $ InlineListType inner size _ -> return $ InlineListType inner size
_ -> makeError (declNamePos n) _ -> makeError (declNamePos n)
"'InlineList' requires exactly two type parameters: a type and a size." "'InlineList' requires exactly two type parameters: a type and a size."
DescBuiltinInlineData -> case params of
[TypeParameterInteger size] -> return $ InlineDataType size
_ -> makeError (declNamePos n)
"'InlineData' requires exactly one type parameter: the byte size of the data."
_ -> case params of _ -> case params of
[] -> descAsType n desc [] -> descAsType n desc
_ -> makeError (declNamePos n) $ _ -> makeError (declNamePos n) $
...@@ -881,6 +897,10 @@ compileDecl scope ...@@ -881,6 +897,10 @@ compileDecl scope
recover () (case typeDesc of recover () (case typeDesc of
InlineStructType _ -> InlineStructType _ ->
makeError defaultPos "Inline fields cannot have default values." makeError defaultPos "Inline fields cannot have default values."
InlineListType _ _ ->
makeError defaultPos "Inline fields cannot have default values."
InlineDataType _ ->
makeError defaultPos "Inline fields cannot have default values."
_ -> return ()) _ -> return ())
return result return result
Nothing -> return Nothing Nothing -> return Nothing
......
...@@ -92,11 +92,16 @@ isPrimitive (InlineStructType _) = False ...@@ -92,11 +92,16 @@ isPrimitive (InlineStructType _) = False
isPrimitive (InterfaceType _) = False isPrimitive (InterfaceType _) = False
isPrimitive (ListType _) = False isPrimitive (ListType _) = False
isPrimitive (InlineListType _ _) = False isPrimitive (InlineListType _ _) = False
isPrimitive (InlineDataType _) = False
isBlob (BuiltinType BuiltinText) = True isBlob (BuiltinType BuiltinText) = True
isBlob (BuiltinType BuiltinData) = True isBlob (BuiltinType BuiltinData) = True
isBlob (InlineDataType _) = True
isBlob _ = False isBlob _ = False
isInlineBlob (InlineDataType _) = True
isInlineBlob _ = False
isStruct (StructType _) = True isStruct (StructType _) = True
isStruct (InlineStructType _) = True isStruct (InlineStructType _) = True
isStruct _ = False isStruct _ = False
...@@ -116,6 +121,18 @@ isPrimitiveList (ListType t) = isPrimitive t ...@@ -116,6 +121,18 @@ isPrimitiveList (ListType t) = isPrimitive t
isPrimitiveList (InlineListType t _) = isPrimitive t isPrimitiveList (InlineListType t _) = isPrimitive t
isPrimitiveList _ = False isPrimitiveList _ = False
isPointerElement (InlineDataType _) = False
isPointerElement t = not (isPrimitive t || isStruct t || isInlineList t)
isPointerList (ListType t) = isPointerElement t
isPointerList (InlineListType t _) = isPointerElement t
isPointerList _ = False
isInlineBlobList (ListType t) = isInlineBlob t
isInlineBlobList _ = False
isStructList (ListType t@(InlineListType _ _)) = isStructList t
isStructList (InlineListType t@(InlineListType _ _) _) = isStructList t
isStructList (ListType t) = isStruct t isStructList (ListType t) = isStruct t
isStructList (InlineListType t _) = isStruct t isStructList (InlineListType t _) = isStruct t
isStructList _ = False isStructList _ = False
...@@ -125,8 +142,20 @@ isInlineList _ = False ...@@ -125,8 +142,20 @@ isInlineList _ = False
blobTypeString (BuiltinType BuiltinText) = "Text" blobTypeString (BuiltinType BuiltinText) = "Text"
blobTypeString (BuiltinType BuiltinData) = "Data" blobTypeString (BuiltinType BuiltinData) = "Data"
blobTypeString (InlineDataType _) = "Data"
blobTypeString (ListType t) = blobTypeString t
blobTypeString (InlineListType t _) = blobTypeString t
blobTypeString _ = error "Not a blob." blobTypeString _ = error "Not a blob."
inlineMultiplier (InlineListType t s) = s * inlineMultiplier t
inlineMultiplier (InlineDataType s) = s
inlineMultiplier _ = 1
listInlineMultiplierString (ListType t) = case inlineMultiplier t of
1 -> ""
s -> " * " ++ show s
listInlineMultiplierString _ = error "Not a list."
cxxTypeString (BuiltinType BuiltinVoid) = " ::capnproto::Void" cxxTypeString (BuiltinType BuiltinVoid) = " ::capnproto::Void"
cxxTypeString (BuiltinType BuiltinBool) = "bool" cxxTypeString (BuiltinType BuiltinBool) = "bool"
cxxTypeString (BuiltinType BuiltinInt8) = " ::int8_t" cxxTypeString (BuiltinType BuiltinInt8) = " ::int8_t"
...@@ -146,7 +175,10 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc ...@@ -146,7 +175,10 @@ cxxTypeString (StructType desc) = globalName $ DescStruct desc
cxxTypeString (InlineStructType desc) = globalName $ DescStruct desc cxxTypeString (InlineStructType desc) = globalName $ DescStruct desc
cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc cxxTypeString (InterfaceType desc) = globalName $ DescInterface desc
cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"] cxxTypeString (ListType t) = concat [" ::capnproto::List<", cxxTypeString t, ">"]
cxxTypeString (InlineListType t _) = concat [" ::capnproto::List<", cxxTypeString t, ">"] cxxTypeString (InlineListType t s) =
concat [" ::capnproto::InlineList<", cxxTypeString t, ", ", show s, ">"]
cxxTypeString (InlineDataType s) =
concat [" ::capnproto::InlineData<", show s, ">"]
cxxFieldSizeString SizeVoid = "VOID"; cxxFieldSizeString SizeVoid = "VOID";
cxxFieldSizeString (SizeData Size1) = "BIT"; cxxFieldSizeString (SizeData Size1) = "BIT";
...@@ -214,6 +246,10 @@ elementType (ListType t) = t ...@@ -214,6 +246,10 @@ elementType (ListType t) = t
elementType (InlineListType t _) = t elementType (InlineListType t _) = t
elementType _ = error "Called elementType on non-list." elementType _ = error "Called elementType on non-list."
inlineElementType (ListType t@(InlineListType _ _)) = inlineElementType t
inlineElementType (InlineListType t@(InlineListType _ _) _) = inlineElementType t
inlineElementType t = elementType t
repeatedlyTake _ [] = [] repeatedlyTake _ [] = []
repeatedlyTake n l = take n l : repeatedlyTake n (drop n l) repeatedlyTake n l = take n l : repeatedlyTake n (drop n l)
...@@ -247,11 +283,14 @@ fieldContext parent desc = mkStrContext context where ...@@ -247,11 +283,14 @@ fieldContext parent desc = mkStrContext context where
context "fieldUpperCase" = MuVariable $ toUpperCaseWithUnderscores $ fieldName desc context "fieldUpperCase" = MuVariable $ toUpperCaseWithUnderscores $ fieldName desc
context "fieldIsPrimitive" = MuBool $ isPrimitive $ fieldType desc context "fieldIsPrimitive" = MuBool $ isPrimitive $ fieldType desc
context "fieldIsBlob" = MuBool $ isBlob $ fieldType desc context "fieldIsBlob" = MuBool $ isBlob $ fieldType desc
context "fieldIsInlineBlob" = MuBool $ isInlineBlob $ fieldType desc
context "fieldIsStruct" = MuBool $ isStruct $ fieldType desc context "fieldIsStruct" = MuBool $ isStruct $ fieldType desc
context "fieldIsInlineStruct" = MuBool $ isInlineStruct $ fieldType desc context "fieldIsInlineStruct" = MuBool $ isInlineStruct $ fieldType desc
context "fieldIsList" = MuBool $ isList $ fieldType desc context "fieldIsList" = MuBool $ isList $ fieldType desc
context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc context "fieldIsNonStructList" = MuBool $ isNonStructList $ fieldType desc
context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc context "fieldIsPrimitiveList" = MuBool $ isPrimitiveList $ fieldType desc
context "fieldIsPointerList" = MuBool $ isPointerList $ fieldType desc
context "fieldIsInlineBlobList" = MuBool $ isInlineBlobList $ fieldType desc
context "fieldIsStructList" = MuBool $ isStructList $ fieldType desc context "fieldIsStructList" = MuBool $ isStructList $ fieldType desc
context "fieldIsInlineList" = MuBool $ isInlineList $ fieldType desc context "fieldIsInlineList" = MuBool $ isInlineList $ fieldType desc
context "fieldDefaultBytes" = context "fieldDefaultBytes" =
...@@ -263,6 +302,7 @@ fieldContext parent desc = mkStrContext context where ...@@ -263,6 +302,7 @@ fieldContext parent desc = mkStrContext context where
context "fieldOffset" = MuVariable $ fieldOffsetInteger $ fieldOffset desc context "fieldOffset" = MuVariable $ fieldOffsetInteger $ fieldOffset desc
context "fieldInlineListSize" = case fieldType desc of context "fieldInlineListSize" = case fieldType desc of
InlineListType _ n -> MuVariable n InlineListType _ n -> MuVariable n
InlineDataType n -> MuVariable n
_ -> muNull _ -> muNull
context "fieldInlineDataOffset" = case fieldOffset desc of context "fieldInlineDataOffset" = case fieldOffset desc of
InlineCompositeOffset off _ size _ -> InlineCompositeOffset off _ size _ ->
...@@ -278,13 +318,16 @@ fieldContext parent desc = mkStrContext context where ...@@ -278,13 +318,16 @@ fieldContext parent desc = mkStrContext context where
context "fieldInlinePointerSize" = case fieldOffset desc of context "fieldInlinePointerSize" = case fieldOffset desc of
InlineCompositeOffset _ _ _ size -> MuVariable size InlineCompositeOffset _ _ _ size -> MuVariable size
_ -> muNull _ -> muNull
context "fieldInlineMultiplier" = MuVariable $ listInlineMultiplierString $ fieldType desc
context "fieldDefaultMask" = case fieldDefaultValue desc of context "fieldDefaultMask" = case fieldDefaultValue desc of
Nothing -> MuVariable "" Nothing -> MuVariable ""
Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v) Just v -> MuVariable (if isDefaultZero v then "" else ", " ++ defaultMask v)
context "fieldElementSize" = context "fieldElementSize" =
MuVariable $ cxxFieldSizeString $ fieldSize $ elementType $ fieldType desc MuVariable $ cxxFieldSizeString $ fieldSize $ inlineElementType $ fieldType desc
context "fieldElementType" = context "fieldElementType" =
MuVariable $ cxxTypeString $ elementType $ fieldType desc MuVariable $ cxxTypeString $ elementType $ fieldType desc
context "fieldInlineElementType" =
MuVariable $ cxxTypeString $ inlineElementType $ fieldType desc
context "fieldUnion" = case fieldUnion desc of context "fieldUnion" = case fieldUnion desc of
Just (u, _) -> muJust $ unionContext context u Just (u, _) -> muJust $ unionContext context u
Nothing -> muNull Nothing -> muNull
......
...@@ -57,6 +57,7 @@ data Desc = DescFile FileDesc ...@@ -57,6 +57,7 @@ data Desc = DescFile FileDesc
| DescBuiltinList | DescBuiltinList
| DescBuiltinInline | DescBuiltinInline
| DescBuiltinInlineList | DescBuiltinInlineList
| DescBuiltinInlineData
| DescBuiltinId | DescBuiltinId
descName (DescFile _) = "(top-level)" descName (DescFile _) = "(top-level)"
...@@ -75,6 +76,7 @@ descName (DescBuiltinType d) = builtinTypeName d ...@@ -75,6 +76,7 @@ descName (DescBuiltinType d) = builtinTypeName d
descName DescBuiltinList = "List" descName DescBuiltinList = "List"
descName DescBuiltinInline = "Inline" descName DescBuiltinInline = "Inline"
descName DescBuiltinInlineList = "InlineList" descName DescBuiltinInlineList = "InlineList"
descName DescBuiltinInlineData = "InlineData"
descName DescBuiltinId = "id" descName DescBuiltinId = "id"
descId (DescFile d) = fileId d descId (DescFile d) = fileId d
...@@ -93,6 +95,7 @@ descId (DescBuiltinType _) = Nothing ...@@ -93,6 +95,7 @@ descId (DescBuiltinType _) = Nothing
descId DescBuiltinList = Nothing descId DescBuiltinList = Nothing
descId DescBuiltinInline = Nothing descId DescBuiltinInline = Nothing
descId DescBuiltinInlineList = Nothing descId DescBuiltinInlineList = Nothing
descId DescBuiltinInlineData = Nothing
descId DescBuiltinId = Just "0U0T3e_SnatEfk6UcH2tcjTt1E0" descId DescBuiltinId = Just "0U0T3e_SnatEfk6UcH2tcjTt1E0"
-- Gets the ID if explicitly defined, or generates it by appending ".name" to the parent's ID. -- Gets the ID if explicitly defined, or generates it by appending ".name" to the parent's ID.
...@@ -119,6 +122,7 @@ descParent (DescBuiltinType _) = error "Builtin type has no parent." ...@@ -119,6 +122,7 @@ descParent (DescBuiltinType _) = error "Builtin type has no parent."
descParent DescBuiltinList = error "Builtin type has no parent." descParent DescBuiltinList = error "Builtin type has no parent."
descParent DescBuiltinInline = error "Builtin type has no parent." descParent DescBuiltinInline = error "Builtin type has no parent."
descParent DescBuiltinInlineList = error "Builtin type has no parent." descParent DescBuiltinInlineList = error "Builtin type has no parent."
descParent DescBuiltinInlineData = error "Builtin type has no parent."
descParent DescBuiltinId = error "Builtin annotation has no parent." descParent DescBuiltinId = error "Builtin annotation has no parent."
descFile (DescFile d) = d descFile (DescFile d) = d
...@@ -140,6 +144,7 @@ descAnnotations (DescBuiltinType _) = Map.empty ...@@ -140,6 +144,7 @@ descAnnotations (DescBuiltinType _) = Map.empty
descAnnotations DescBuiltinList = Map.empty descAnnotations DescBuiltinList = Map.empty
descAnnotations DescBuiltinInline = Map.empty descAnnotations DescBuiltinInline = Map.empty
descAnnotations DescBuiltinInlineList = Map.empty descAnnotations DescBuiltinInlineList = Map.empty
descAnnotations DescBuiltinInlineData = Map.empty
descAnnotations DescBuiltinId = Map.empty descAnnotations DescBuiltinId = Map.empty
descRuntimeImports (DescFile _) = error "Not to be called on files." descRuntimeImports (DescFile _) = error "Not to be called on files."
...@@ -158,6 +163,7 @@ descRuntimeImports (DescBuiltinType _) = [] ...@@ -158,6 +163,7 @@ descRuntimeImports (DescBuiltinType _) = []
descRuntimeImports DescBuiltinList = [] descRuntimeImports DescBuiltinList = []
descRuntimeImports DescBuiltinInline = [] descRuntimeImports DescBuiltinInline = []
descRuntimeImports DescBuiltinInlineList = [] descRuntimeImports DescBuiltinInlineList = []
descRuntimeImports DescBuiltinInlineData = []
descRuntimeImports DescBuiltinId = [] descRuntimeImports DescBuiltinId = []
type MemberMap = Map.Map String (Maybe Desc) type MemberMap = Map.Map String (Maybe Desc)
...@@ -228,6 +234,7 @@ data TypeDesc = BuiltinType BuiltinType ...@@ -228,6 +234,7 @@ data TypeDesc = BuiltinType BuiltinType
| InterfaceType InterfaceDesc | InterfaceType InterfaceDesc
| ListType TypeDesc | ListType TypeDesc
| InlineListType TypeDesc Integer | InlineListType TypeDesc Integer
| InlineDataType Integer
typeRuntimeImports (BuiltinType _) = [] typeRuntimeImports (BuiltinType _) = []
typeRuntimeImports (EnumType d) = [descFile (DescEnum d)] typeRuntimeImports (EnumType d) = [descFile (DescEnum d)]
...@@ -236,6 +243,7 @@ typeRuntimeImports (InlineStructType d) = [descFile (DescStruct d)] ...@@ -236,6 +243,7 @@ typeRuntimeImports (InlineStructType d) = [descFile (DescStruct d)]
typeRuntimeImports (InterfaceType d) = [descFile (DescInterface d)] typeRuntimeImports (InterfaceType d) = [descFile (DescInterface d)]
typeRuntimeImports (ListType d) = typeRuntimeImports d typeRuntimeImports (ListType d) = typeRuntimeImports d
typeRuntimeImports (InlineListType d _) = typeRuntimeImports d typeRuntimeImports (InlineListType d _) = typeRuntimeImports d
typeRuntimeImports (InlineDataType _) = []
data DataSectionSize = DataSection1 | DataSection8 | DataSection16 | DataSection32 data DataSectionSize = DataSection1 | DataSection8 | DataSection16 | DataSection32
| DataSectionWords Integer | DataSectionWords Integer
...@@ -337,6 +345,12 @@ fieldSize (InlineListType element size) = let ...@@ -337,6 +345,12 @@ fieldSize (InlineListType element size) = let
SizeReference -> size SizeReference -> size
SizeInlineComposite _ pc -> pc * size SizeInlineComposite _ pc -> pc * size
in SizeInlineComposite dataSection pointerCount in SizeInlineComposite dataSection pointerCount
fieldSize (InlineDataType size)
| size <= 0 = SizeInlineComposite (DataSectionWords 0) 0
| size <= 1 = SizeInlineComposite DataSection8 0
| size <= 2 = SizeInlineComposite DataSection16 0
| size <= 4 = SizeInlineComposite DataSection32 0
| otherwise = SizeInlineComposite (DataSectionWords (div (size + 7) 8)) 0
-- Render the type descriptor's name as a string, appropriate for use in the given scope. -- Render the type descriptor's name as a string, appropriate for use in the given scope.
typeName :: Desc -> TypeDesc -> String typeName :: Desc -> TypeDesc -> String
...@@ -347,6 +361,7 @@ typeName scope (InlineStructType desc) = descQualifiedName scope (DescStruct des ...@@ -347,6 +361,7 @@ typeName scope (InlineStructType desc) = descQualifiedName scope (DescStruct des
typeName scope (InterfaceType desc) = descQualifiedName scope (DescInterface desc) typeName scope (InterfaceType desc) = descQualifiedName scope (DescInterface desc)
typeName scope (ListType t) = "List(" ++ typeName scope t ++ ")" typeName scope (ListType t) = "List(" ++ typeName scope t ++ ")"
typeName scope (InlineListType t s) = printf "InlineList(%s, %d)" (typeName scope t) s typeName scope (InlineListType t s) = printf "InlineList(%s, %d)" (typeName scope t) s
typeName scope (InlineDataType s) = printf "InlineData(%d)" s
-- Computes the qualified name for the given descriptor within the given scope. -- Computes the qualified name for the given descriptor within the given scope.
-- At present the scope is only used to determine whether the target is in the same file. If -- At present the scope is only used to determine whether the target is in the same file. If
...@@ -605,6 +620,7 @@ descToCode _ (DescBuiltinType _) = error "Can't print code for builtin type." ...@@ -605,6 +620,7 @@ descToCode _ (DescBuiltinType _) = error "Can't print code for builtin type."
descToCode _ DescBuiltinList = error "Can't print code for builtin type." descToCode _ DescBuiltinList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInline = error "Can't print code for builtin type." descToCode _ DescBuiltinInline = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineList = error "Can't print code for builtin type." descToCode _ DescBuiltinInlineList = error "Can't print code for builtin type."
descToCode _ DescBuiltinInlineData = error "Can't print code for builtin type."
descToCode _ DescBuiltinId = error "Can't print code for builtin annotation." descToCode _ DescBuiltinId = error "Can't print code for builtin annotation."
maybeBlockCode :: String -> [Desc] -> String maybeBlockCode :: String -> [Desc] -> String
......
...@@ -88,6 +88,8 @@ encodePointerValue (InlineStructType _) _ = ...@@ -88,6 +88,8 @@ encodePointerValue (InlineStructType _) _ =
encodePointerValue (ListType elementType) (ListDesc items) = encodeList elementType items encodePointerValue (ListType elementType) (ListDesc items) = encodeList elementType items
encodePointerValue (InlineListType _ _) _ = encodePointerValue (InlineListType _ _) _ =
error "Tried to encode inline list as a pointer." error "Tried to encode inline list as a pointer."
encodePointerValue (InlineDataType _) _ =
error "Tried to encode inline data as a pointer."
encodePointerValue _ _ = error "Unknown pointer type." encodePointerValue _ _ = error "Unknown pointer type."
-- Given a sorted list of (bitOffset, data), pack into a byte array. -- Given a sorted list of (bitOffset, data), pack into a byte array.
...@@ -191,6 +193,7 @@ structDataSectionValues assignments = let ...@@ -191,6 +193,7 @@ structDataSectionValues assignments = let
(pos, v2) <- case (t, v) of (pos, v2) <- case (t, v) of
(InlineStructType _, StructValueDesc v2) -> structDataSectionValues v2 (InlineStructType _, StructValueDesc v2) -> structDataSectionValues v2
(InlineListType t2 _, ListDesc v2) -> inlineListDataSectionValues t2 v2 (InlineListType t2 _, ListDesc v2) -> inlineListDataSectionValues t2 v2
(InlineDataType _, DataDesc v2) -> [(0, EncodedBytes v2)]
_ -> error "Non-inline-composite had inline-composite offset." _ -> error "Non-inline-composite had inline-composite offset."
return (pos + bitOffset, v2) return (pos + bitOffset, v2)
...@@ -211,6 +214,7 @@ structPointerSectionValues assignments = let ...@@ -211,6 +214,7 @@ structPointerSectionValues assignments = let
(pos, v2) <- case (t, v) of (pos, v2) <- case (t, v) of
(InlineStructType _, StructValueDesc v2) -> structPointerSectionValues v2 (InlineStructType _, StructValueDesc v2) -> structPointerSectionValues v2
(InlineListType t2 _, ListDesc v2) -> inlineListPointerSectionValues t2 v2 (InlineListType t2 _, ListDesc v2) -> inlineListPointerSectionValues t2 v2
(InlineDataType _, DataDesc _) -> []
_ -> error "Non-inline-composite had inline-composite offset." _ -> error "Non-inline-composite had inline-composite offset."
return (pos + off, v2) return (pos + off, v2)
...@@ -261,29 +265,21 @@ encodeList (StructType desc) elements = let ...@@ -261,29 +265,21 @@ encodeList (StructType desc) elements = let
(genericLength elements), (genericLength elements),
concat [tag, elemBytes, childBytes]) concat [tag, elemBytes, childBytes])
-- A list of inline structs is encoded into separate data and pointer sections, and the encodeList (InlineStructType _) _ = error "Not supported: List of inline structs."
-- pointer to it is actually a struct pointer.
encodeList (InlineStructType desc) elements = let
dataBytes = inlineStructListDataSection desc elements
(refBytes, childBytes) = inlineStructListPointerSection desc elements
in case (structDataSize desc, structPointerCount desc) of
(ds, 0) -> -- If only data, encode as a primitive list.
(encodeListReference (SizeData $ dataSectionAlignment ds)
(div (genericLength elements * dataSectionBits ds)
(dataSizeInBits (dataSectionAlignment ds))),
dataBytes)
(DataSectionWords 0, pc) -> -- If only pointers, encode as a pointer list.
(encodeListReference SizeReference (genericLength elements * pc),
refBytes ++ childBytes)
(ds, pc) -> -- Otherwise, encode as a struct.
(encodeInlineStructListReference ds pc (genericLength elements),
concat [dataBytes, refBytes, childBytes])
-- Encode a list of inline lists by just concatenating all the elements. The number of inner -- Encode a list of inline lists by just concatenating all the elements. The number of inner
-- lists can be determined at runtime by dividing the total size by the fixed inline list size. -- lists can be determined at runtime by dividing the total size by the fixed inline list size.
-- Note that this means if you have something like List(InlineList(UInt8, 3)) and the list has
-- two elements, the total size will be 6 bytes -- we don't round the individual sub-lists up
-- to power-of-two boundaries.
encodeList (InlineListType (InlineStructType t) _) elements =
encodeList (StructType t) (concat [l | ListDesc l <- elements])
encodeList (InlineListType t _) elements = encodeList t (concat [l | ListDesc l <- elements]) encodeList (InlineListType t _) elements = encodeList t (concat [l | ListDesc l <- elements])
-- Encode a list of inline data. Similar deal to above.
encodeList (InlineDataType _) elements =
encodePointerValue (BuiltinType BuiltinData) (DataDesc $ concat [l | DataDesc l <- elements])
-- Encode primitive types. -- Encode primitive types.
encodeList elementType elements = let encodeList elementType elements = let
eSize = fieldSize elementType eSize = fieldSize elementType
...@@ -306,6 +302,7 @@ inlineListDataSectionValues elementType elements = case fieldSize elementType of ...@@ -306,6 +302,7 @@ inlineListDataSectionValues elementType elements = case fieldSize elementType of
(SizeInlineComposite _ _) -> case elementType of (SizeInlineComposite _ _) -> case elementType of
InlineStructType desc -> inlineStructListDataSectionValues desc elements InlineStructType desc -> inlineStructListDataSectionValues desc elements
InlineListType t _ -> inlineListDataSectionValues t (concat [l | ListDesc l <- elements]) InlineListType t _ -> inlineListDataSectionValues t (concat [l | ListDesc l <- elements])
InlineDataType _ -> [(0, EncodedBytes $ concat [l | DataDesc l <- elements])]
_ -> error "Unknown inline composite type." _ -> error "Unknown inline composite type."
SizeReference -> [] SizeReference -> []
SizeData size -> let SizeData size -> let
...@@ -317,6 +314,7 @@ inlineListPointerSectionValues elementType elements = case fieldSize elementType ...@@ -317,6 +314,7 @@ inlineListPointerSectionValues elementType elements = case fieldSize elementType
(SizeInlineComposite _ _) -> case elementType of (SizeInlineComposite _ _) -> case elementType of
InlineStructType desc -> inlineStructListPointerSectionValues desc elements InlineStructType desc -> inlineStructListPointerSectionValues desc elements
InlineListType t _ -> inlineListPointerSectionValues t (concat [l | ListDesc l <- elements]) InlineListType t _ -> inlineListPointerSectionValues t (concat [l | ListDesc l <- elements])
InlineDataType _ -> []
_ -> error "Unknown inline composite type." _ -> error "Unknown inline composite type."
SizeReference -> zip [0..] $ map (encodePointerValue elementType) elements SizeReference -> zip [0..] $ map (encodePointerValue elementType) elements
SizeData _ -> [] SizeData _ -> []
...@@ -348,9 +346,7 @@ inlineStructListPointerSectionValues elementDesc elements = do ...@@ -348,9 +346,7 @@ inlineStructListPointerSectionValues elementDesc elements = do
encodeMessage (StructType desc) (StructValueDesc assignments) = let encodeMessage (StructType desc) (StructValueDesc assignments) = let
(dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0 (dataBytes, refBytes, childBytes) = encodeStruct desc assignments 0
in concat [encodeStructReference desc (0::Integer), dataBytes, refBytes, childBytes] in concat [encodeStructReference desc (0::Integer), dataBytes, refBytes, childBytes]
encodeMessage (InlineStructType desc) val = encodeMessage (StructType desc) val
encodeMessage (ListType elementType) (ListDesc elements) = let encodeMessage (ListType elementType) (ListDesc elements) = let
(ptr, listBytes) = encodeList elementType elements (ptr, listBytes) = encodeList elementType elements
in ptr (0::Integer) ++ listBytes in ptr (0::Integer) ++ listBytes
encodeMessage (InlineListType elementType _) val = encodeMessage (ListType elementType) val
encodeMessage _ _ = error "Not a message." encodeMessage _ _ = error "Not a message."
...@@ -166,13 +166,13 @@ public: ...@@ -166,13 +166,13 @@ public:
{{#fieldIsBlob}} {{#fieldIsBlob}}
inline {{fieldType}}::Builder get{{fieldTitleCase}}(); inline {{fieldType}}::Builder get{{fieldTitleCase}}();
inline void set{{fieldTitleCase}}({{fieldType}}::Reader value); inline void set{{fieldTitleCase}}({{fieldType}}::Reader value);
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size); inline {{fieldType}}::Builder init{{fieldTitleCase}}({{^fieldIsInlineBlob}}unsigned int size{{/fieldIsInlineBlob}});
{{/fieldIsBlob}} {{/fieldIsBlob}}
{{#fieldIsStruct}} {{#fieldIsStruct}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(); inline {{fieldType}}::Builder init{{fieldTitleCase}}();
inline {{fieldType}}::Builder get{{fieldTitleCase}}(); inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{#fieldIsNonStructList}} {{#fieldIsList}}
{{#fieldIsInlineList}} {{#fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(); inline {{fieldType}}::Builder init{{fieldTitleCase}}();
{{/fieldIsInlineList}} {{/fieldIsInlineList}}
...@@ -188,16 +188,7 @@ public: ...@@ -188,16 +188,7 @@ public:
{{^fieldIsPrimitiveList}} {{^fieldIsPrimitiveList}}
inline void set{{fieldTitleCase}}(std::initializer_list<{{fieldElementType}}::Reader> other); inline void set{{fieldTitleCase}}(std::initializer_list<{{fieldElementType}}::Reader> other);
{{/fieldIsPrimitiveList}} {{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}} {{/fieldIsList}}
{{#fieldIsStructList}}
{{#fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}();
{{/fieldIsInlineList}}
{{^fieldIsInlineList}}
inline {{fieldType}}::Builder init{{fieldTitleCase}}(unsigned int size);
{{/fieldIsInlineList}}
inline {{fieldType}}::Builder get{{fieldTitleCase}}();
{{/fieldIsStructList}}
{{/typeFields}} {{/typeFields}}
private: private:
::capnproto::internal::StructBuilder _builder; ::capnproto::internal::StructBuilder _builder;
...@@ -264,6 +255,47 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}} value ...@@ -264,6 +255,47 @@ inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}} value
{{/fieldIsPrimitive}} {{/fieldIsPrimitive}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsBlob}} {{#fieldIsBlob}}
{{#fieldIsInlineBlob}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _reader.getInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return _builder.getInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}({{fieldType}}::Reader value) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
_builder.setInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES,
value);
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return _builder.initInline{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlineListSize}} * ::capnproto::BYTES);
}
{{/fieldIsInlineBlob}}
{{^fieldIsInlineBlob}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -303,6 +335,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}( ...@@ -303,6 +335,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
return _builder.init{{fieldBlobType}}Field( return _builder.init{{fieldBlobType}}Field(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::BYTES); {{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::BYTES);
} }
{{/fieldIsInlineBlob}}
{{/fieldIsBlob}} {{/fieldIsBlob}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStruct}} {{#fieldIsStruct}}
...@@ -366,7 +399,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -366,7 +399,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{/fieldIsInlineStruct}} {{/fieldIsInlineStruct}}
{{/fieldIsStruct}} {{/fieldIsStruct}}
{{! ------------------------------------------------------------------------------------------- }} {{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsNonStructList}} {{#fieldIsList}}
{{#fieldIsInlineList}} {{#fieldIsInlineList}}
{{#fieldIsPrimitiveList}} {{#fieldIsPrimitiveList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
...@@ -402,7 +435,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -402,7 +435,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
::capnproto::internal::FieldSize::{{fieldElementSize}})); ::capnproto::internal::FieldSize::{{fieldElementSize}}));
} }
{{/fieldIsPrimitiveList}} {{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}} {{#fieldIsPointerList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -432,10 +465,48 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -432,10 +465,48 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES, {{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS)); {{fieldInlineListSize}} * ::capnproto::ELEMENTS));
} }
{{/fieldIsPrimitiveList}} {{/fieldIsPointerList}}
{{#fieldIsStructList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Reader(_reader.getInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member.");
{{/fieldUnion}}
return {{fieldType}}::Builder(_builder.getInlineStructListField(
{{fieldInlineDataOffset}} * ::capnproto::BYTES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
}
{{/fieldIsStructList}}
{{/fieldIsInlineList}} {{/fieldIsInlineList}}
{{! --------------------------------- }} {{! --------------------------------- }}
{{^fieldIsInlineList}} {{^fieldIsInlineList}}
{{^fieldIsStructList}}
{{^fieldIsInlineBlobList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -456,7 +527,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}( ...@@ -456,7 +527,7 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
return {{fieldType}}::Builder(_builder.initListField( return {{fieldType}}::Builder(_builder.initListField(
{{fieldOffset}} * ::capnproto::REFERENCES, {{fieldOffset}} * ::capnproto::REFERENCES,
::capnproto::internal::FieldSize::{{fieldElementSize}}, ::capnproto::internal::FieldSize::{{fieldElementSize}},
size * ::capnproto::ELEMENTS)); size{{fieldInlineMultiplier}} * ::capnproto::ELEMENTS));
} }
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
...@@ -468,77 +539,37 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -468,77 +539,37 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsInlineList}} {{/fieldIsInlineBlobList}}
{{! --------------------------------- }} {{/fieldIsStructList}}
{{#fieldIsInlineBlobList}}
template <typename _t>
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(const _t& other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{#fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}::Reader> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{/fieldIsNonStructList}}
{{! ------------------------------------------------------------------------------------------- }}
{{#fieldIsStructList}}
{{#fieldIsInlineList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member."); "Must check which() before get()ing a union member.");
{{/fieldUnion}} {{/fieldUnion}}
return {{fieldType}}::Reader(_reader.getInlineStructListField( return {{fieldType}}::Reader(_reader.get{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES, {{fieldOffset}} * ::capnproto::REFERENCES, nullptr, 0 * ::capnproto::BYTES));
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
} }
inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(unsigned int size) {
{{#fieldUnion}} {{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>( _builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}}); {{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}} {{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initInlineStructListField( return {{fieldType}}::Builder(_builder.init{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES, {{fieldOffset}} * ::capnproto::REFERENCES,
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES, size{{fieldInlineMultiplier}} * ::capnproto::BYTES));
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
} }
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
"Must check which() before get()ing a union member."); "Must check which() before get()ing a union member.");
{{/fieldUnion}} {{/fieldUnion}}
return {{fieldType}}::Builder(_builder.getInlineStructListField( return {{fieldType}}::Builder(_builder.get{{fieldBlobType}}Field(
{{fieldInlineDataOffset}} * ::capnproto::BYTES, {{fieldOffset}} * ::capnproto::REFERENCES, nullptr, 0 * ::capnproto::BYTES));
{{fieldInlinePointerOffset}} * ::capnproto::REFERENCES,
{{fieldInlineListSize}} * ::capnproto::ELEMENTS,
{{fieldElementType}}::STRUCT_SIZE));
} }
{{/fieldIsInlineList}} {{/fieldIsInlineBlobList}}
{{^fieldIsInlineList}} {{#fieldIsStructList}}
inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() { inline {{fieldType}}::Reader {{typeFullName}}::Reader::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}}, CAPNPROTO_INLINE_DPRECOND(which() == {{unionTitleCase}}::{{fieldUpperCase}},
...@@ -557,8 +588,9 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}( ...@@ -557,8 +588,9 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::init{{fieldTitleCase}}(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}}); {{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}} {{/fieldUnion}}
return {{fieldType}}::Builder(_builder.initStructListField( return {{fieldType}}::Builder(_builder.initStructListField(
{{fieldOffset}} * ::capnproto::REFERENCES, size * ::capnproto::ELEMENTS, {{fieldOffset}} * ::capnproto::REFERENCES,
{{fieldElementType}}::STRUCT_SIZE)); size{{fieldInlineMultiplier}} * ::capnproto::ELEMENTS,
{{fieldInlineElementType}}::STRUCT_SIZE));
} }
inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() { inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() {
{{#fieldUnion}} {{#fieldUnion}}
...@@ -570,8 +602,40 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}() ...@@ -570,8 +602,40 @@ inline {{fieldType}}::Builder {{typeFullName}}::Builder::get{{fieldTitleCase}}()
{{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}} {{#fieldDefaultBytes}}DEFAULT_{{fieldUpperCase}}.words{{/fieldDefaultBytes}}
{{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}})); {{^fieldDefaultBytes}}nullptr{{/fieldDefaultBytes}}));
} }
{{/fieldIsInlineList}}
{{/fieldIsStructList}} {{/fieldIsStructList}}
{{/fieldIsInlineList}}
{{! --------------------------------- }}
template <typename _t>
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(const _t& other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{#fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{^fieldIsPrimitiveList}}
inline void {{typeFullName}}::Builder::set{{fieldTitleCase}}(
std::initializer_list<{{fieldElementType}}::Reader> other) {
{{#fieldUnion}}
_builder.setDataField<{{unionTitleCase}}::Which>(
{{unionTagOffset}} * ::capnproto::ELEMENTS, {{unionTitleCase}}::{{fieldUpperCase}});
{{/fieldUnion}}
init{{fieldTitleCase}}({{^fieldIsInlineList}}other.size(){{/fieldIsInlineList}}).copyFrom(other);
}
{{/fieldIsPrimitiveList}}
{{/fieldIsList}}
{{! ------------------------------------------------------------------------------------------- }}
{{/typeFields}} {{/typeFields}}
{{/typeStructOrUnion}} {{/typeStructOrUnion}}
{{/fileTypes}} {{/fileTypes}}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment