Commit 01ac98df authored by Kenton Varda's avatar Kenton Varda

Implement adopt() and disown() for AnyStruct/AnyList fields.

This eliminates a TODO(soon).
parent 8c1cbc54
......@@ -235,6 +235,15 @@ TEST(Any, AnyStructListCapInSchema) {
AnyStruct::Builder anyStruct = root.getAnyStructField();
checkTestMessage(anyStruct.as<TestAllTypes>());
checkTestMessage(anyStruct.asReader().as<TestAllTypes>());
EXPECT_TRUE(root.hasAnyStructField());
auto orphan = root.disownAnyStructField();
checkTestMessage(orphan.getReader().as<TestAllTypes>());
EXPECT_FALSE(root.hasAnyStructField());
root.adoptAnyStructField(kj::mv(orphan));
EXPECT_TRUE(root.hasAnyStructField());
checkTestMessage(root.getAnyStructField().as<TestAllTypes>());
}
{
......@@ -245,9 +254,18 @@ TEST(Any, AnyStructListCapInSchema) {
AnyList::Builder anyList = root.getAnyListField();
checkList(anyList.as<List<int>>(), {123, 456, 789});
EXPECT_TRUE(root.hasAnyListField());
auto orphan = root.disownAnyListField();
checkList(orphan.getReader().as<List<int>>(), {123, 456, 789});
EXPECT_FALSE(root.hasAnyListField());
root.adoptAnyListField(kj::mv(orphan));
EXPECT_TRUE(root.hasAnyListField());
checkList(root.getAnyListField().as<List<int>>(), {123, 456, 789});
}
#if !CAPNP_LITE
#if !CAPNP_LITE
// This portion of the test relies on a Client, not present in lite-mode.
{
kj::EventLoop loop;
......@@ -261,7 +279,7 @@ TEST(Any, AnyStructListCapInSchema) {
req.send().wait(waitScope);
EXPECT_EQ(1, callCount);
}
#endif
#endif
}
KJ_TEST("Builder::isStruct() does not corrupt segment pointer") {
......
......@@ -975,9 +975,12 @@ struct PointerHelpers<AnyStruct, Kind::OTHER> {
bounded(pointerCount) * POINTERS)));
}
// TODO(soon): implement these
static void adopt(PointerBuilder builder, Orphan<AnyStruct>&& value);
static Orphan<AnyStruct> disown(PointerBuilder builder);
static void adopt(PointerBuilder builder, Orphan<AnyStruct>&& value) {
builder.adopt(kj::mv(value.builder));
}
static Orphan<AnyStruct> disown(PointerBuilder builder) {
return Orphan<AnyStruct>(builder.disown());
}
};
template <>
......@@ -1006,9 +1009,12 @@ struct PointerHelpers<AnyList, Kind::OTHER> {
bounded(pointerCount) * POINTERS)));
}
// TODO(soon): implement these
static void adopt(PointerBuilder builder, Orphan<AnyList>&& value);
static Orphan<AnyList> disown(PointerBuilder builder);
static void adopt(PointerBuilder builder, Orphan<AnyList>&& value) {
builder.adopt(kj::mv(value.builder));
}
static Orphan<AnyList> disown(PointerBuilder builder) {
return Orphan<AnyList>(builder.disown());
}
};
template <>
......@@ -1024,6 +1030,19 @@ struct OrphanGetImpl<AnyStruct, Kind::OTHER> {
}
};
template <>
struct OrphanGetImpl<AnyList, Kind::OTHER> {
static inline AnyList::Builder apply(_::OrphanBuilder& builder) {
return AnyList::Builder(builder.asListAnySize());
}
static inline AnyList::Reader applyReader(const _::OrphanBuilder& builder) {
return AnyList::Reader(builder.asListReaderAnySize());
}
static inline void truncateListOf(_::OrphanBuilder& builder, ElementCount size) {
builder.truncate(size, ElementSize::POINTER);
}
};
} // namespace _ (private)
#if !CAPNP_LITE
......
......@@ -3422,6 +3422,18 @@ ListBuilder OrphanBuilder::asStructList(StructSize elementSize) {
return result;
}
ListBuilder OrphanBuilder::asListAnySize() {
KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr));
ListBuilder result = WireHelpers::getWritableListPointerAnySize(
tagAsPtr(), location, segment, capTable, nullptr, segment->getArena());
// Watch out, the pointer could have been updated if the object had to be relocated.
location = result.getLocation();
return result;
}
Text::Builder OrphanBuilder::asText() {
KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr));
......@@ -3450,6 +3462,13 @@ ListReader OrphanBuilder::asListReader(ElementSize elementSize) const {
segment, capTable, tagAsPtr(), location, nullptr, elementSize, kj::maxValue);
}
ListReader OrphanBuilder::asListReaderAnySize() const {
KJ_DASSERT(tagAsPtr()->isNull() == (location == nullptr));
return WireHelpers::readListPointer(
segment, capTable, tagAsPtr(), location, nullptr, ElementSize::VOID /* dummy */,
kj::maxValue);
}
#if !CAPNP_LITE
kj::Own<ClientHook> OrphanBuilder::asCapability() const {
return WireHelpers::readCapabilityPointer(segment, capTable, tagAsPtr(), kj::maxValue);
......
......@@ -897,12 +897,16 @@ public:
ListBuilder asStructList(StructSize elementSize);
// Interpret as a struct list, or throw an exception if not a list.
ListBuilder asListAnySize();
// For AnyList.
Text::Builder asText();
Data::Builder asData();
// Interpret as a blob, or throw an exception if not a blob.
StructReader asStructReader(StructSize size) const;
ListReader asListReader(ElementSize elementSize) const;
ListReader asListReaderAnySize() const;
#if !CAPNP_LITE
kj::Own<ClientHook> asCapability() const;
#endif // !CAPNP_LITE
......
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