Commit ee10f5c6 authored by David Renshaw's avatar David Renshaw

ignore pad bits when checking for bit list equality

parent 83b8dccf
......@@ -354,6 +354,29 @@ TEST(Any, Equals) {
EXPECT_EQ(Equality::EQUAL, anyA.equals(anyB));
}
KJ_TEST("Bit list with nonzero pad bits") {
AlignedData<2> segment1 = {{
0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, // eleven bit-sized elements
0xee, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // twelfth bit is set!
}};
kj::ArrayPtr<const word> segments1[1] = {
kj::arrayPtr(segment1.words, 2)
};
SegmentArrayMessageReader message1(kj::arrayPtr(segments1, 1));
AlignedData<2> segment2 = {{
0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, // eleven bit-sized elements
0xee, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // twelfth bit is not set
}};
kj::ArrayPtr<const word> segments2[1] = {
kj::arrayPtr(segment2.words, 2)
};
SegmentArrayMessageReader message2(kj::arrayPtr(segments2, 1));
// Should be equal, despite nonzero padding.
KJ_ASSERT(message1.getRoot<AnyList>() == message2.getRoot<AnyList>());
}
} // namespace
} // namespace _ (private)
} // namespace capnp
......@@ -148,16 +148,30 @@ Equality AnyList::Reader::equals(AnyList::Reader right) {
case ElementSize::BYTE:
case ElementSize::TWO_BYTES:
case ElementSize::FOUR_BYTES:
case ElementSize::EIGHT_BYTES:
if(getElementSize() == right.getElementSize()) {
if(memcmp(getRawBytes().begin(), right.getRawBytes().begin(), getRawBytes().size()) == 0) {
return Equality::EQUAL;
} else {
case ElementSize::EIGHT_BYTES: {
if (getElementSize() != right.getElementSize()) {
return Equality::NOT_EQUAL;
}
size_t cmpSize = getRawBytes().size();
if (getElementSize() == ElementSize::BIT && size() % 8 != 0) {
// The list does not end on a byte boundary. We need special handling for the final
// byte because we only care about the bits that are actually elements of the list.
uint8_t mask = (1 << (size() % 8)) - 1; // lowest size() bits set
if ((getRawBytes()[cmpSize - 1] & mask) != (right.getRawBytes()[cmpSize - 1] & mask)) {
return Equality::NOT_EQUAL;
}
cmpSize -= 1;
}
if (memcmp(getRawBytes().begin(), right.getRawBytes().begin(), cmpSize) == 0) {
return Equality::EQUAL;
} else {
return Equality::NOT_EQUAL;
}
}
case ElementSize::POINTER:
case ElementSize::INLINE_COMPOSITE: {
auto llist = as<List<AnyStruct>>();
......
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