Skip to content

Commit 7069ede

Browse files
bugfix: handle empty stacks correctly
1 parent 76c4554 commit 7069ede

2 files changed

Lines changed: 46 additions & 6 deletions

File tree

DataFormats/Headers/include/Headers/DataHeader.h

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -524,13 +524,34 @@ struct Stack {
524524
static byte* inject(byte* here, const T& h, const Args... args) noexcept {
525525
auto alsohere = inject(here, h);
526526
// the type might be a stack itself, loop through headers and set the flag in the last one
527-
BaseHeader* next = BaseHeader::get(here);
528-
while (next->flagsNextHeader) {
529-
next = next->next();
527+
if (h.size() > 0) {
528+
BaseHeader* next = BaseHeader::get(here);
529+
while (next->flagsNextHeader) {
530+
next = next->next();
531+
}
532+
next->flagsNextHeader = hasNonEmptyArg(args...);
530533
}
531-
next->flagsNextHeader = true;
532534
return inject(alsohere, args...);
533535
}
536+
537+
// helper function to check if there is at least one non-empty header/stack in the argument pack
538+
template <typename T, typename... Args>
539+
static bool hasNonEmptyArg(const T& h, const Args&... args) noexcept
540+
{
541+
if (h.size() > 0) {
542+
return true;
543+
}
544+
return hasNonEmptyArg(args...);
545+
}
546+
547+
template <typename T>
548+
static bool hasNonEmptyArg(const T& h) noexcept
549+
{
550+
if (h.size() > 0) {
551+
return true;
552+
}
553+
return false;
554+
}
534555
};
535556

536557
//__________________________________________________________________________________________________

DataFormats/Headers/test/testDataHeader.cxx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,35 @@ namespace o2 {
200200
BOOST_CHECK(h2->size() == sizeof(NameHeader<9>));
201201
BOOST_CHECK(h2->getNameLength() == 9);
202202

203+
// create new stack from stack and additional header
203204
auto meta = test::MetaHeader{ 42 };
204205
Stack s2{ s1, meta };
205206
BOOST_CHECK(s2.size() == s1.size() + sizeof(decltype(meta)));
206207

207208
auto* h3 = get<test::MetaHeader*>(s1.data());
208209
BOOST_CHECK(h3 == nullptr);
209210
h3 = get<test::MetaHeader*>(s2.data());
210-
BOOST_CHECK(h3 != nullptr);
211+
BOOST_REQUIRE(h3 != nullptr);
212+
BOOST_CHECK(h3->flagsNextHeader == false);
211213
h1 = get<DataHeader*>(s2.data());
212-
BOOST_CHECK(h1 != nullptr);
214+
BOOST_REQUIRE(h1 != nullptr);
215+
BOOST_CHECK(h1->flagsNextHeader == true);
216+
217+
// create stack from header and empty stack
218+
Stack s3{ meta, Stack{} };
219+
BOOST_CHECK(s3.size() == sizeof(meta));
220+
h3 = get<test::MetaHeader*>(s3.data());
221+
BOOST_REQUIRE(h3 != nullptr);
222+
// no next header to be flagged as the stack was empty
223+
BOOST_CHECK(h3->flagsNextHeader == false);
224+
225+
// create new stack from stack, empty stack, and header
226+
Stack s4{ s1, Stack{}, meta };
227+
BOOST_CHECK(s4.size() == s1.size() + sizeof(meta));
228+
// check if we can find the header even though there was an empty stack in the middle
229+
h3 = get<test::MetaHeader*>(s4.data());
230+
BOOST_REQUIRE(h3 != nullptr);
231+
BOOST_CHECK(h3->secret == 42);
213232
}
214233

215234
BOOST_AUTO_TEST_CASE(Descriptor_benchmark)

0 commit comments

Comments
 (0)