@@ -1799,6 +1799,24 @@ ROOT::RResult<std::uint32_t> ROOT::Internal::RNTupleSerializer::SerializeFooter(
17991799 return R__FORWARD_ERROR (res);
18001800 }
18011801
1802+ // Attributes
1803+ frame = pos;
1804+ const auto &attrSets = ROOT::Experimental::Internal::GetAttributeSets (desc);
1805+ const auto nAttributeSets = attrSets.size ();
1806+ pos += SerializeListFramePreamble (nAttributeSets, *where);
1807+ for (const auto &attrSet : attrSets) {
1808+ if (auto res = SerializeAttributeSet (attrSet, *where)) {
1809+ pos += res.Unwrap ();
1810+ } else {
1811+ return R__FORWARD_ERROR (res);
1812+ }
1813+ }
1814+ if (auto res = SerializeFramePostscript (buffer ? frame : nullptr , pos - frame)) {
1815+ pos += res.Unwrap ();
1816+ } else {
1817+ return R__FORWARD_ERROR (res);
1818+ }
1819+
18021820 std::uint32_t size = pos - base;
18031821 if (auto res = SerializeEnvelopePostscript (base, size)) {
18041822 size += res.Unwrap ();
@@ -1808,6 +1826,35 @@ ROOT::RResult<std::uint32_t> ROOT::Internal::RNTupleSerializer::SerializeFooter(
18081826 return size;
18091827}
18101828
1829+ ROOT::RResult<std::uint32_t > ROOT::Internal::RNTupleSerializer::SerializeAttributeSet (
1830+ const Experimental::Internal::RNTupleAttrSetDescriptor &attrDesc, void *buffer)
1831+ {
1832+ // uncompressed size must fit in 48 bits.
1833+ R__ASSERT (attrDesc.fAnchorUncompLen < (1ull << 48 ));
1834+
1835+ auto base = reinterpret_cast <unsigned char *>(buffer);
1836+ auto pos = base;
1837+ void **where = (buffer == nullptr ) ? &buffer : reinterpret_cast <void **>(&pos);
1838+
1839+ const std::uint64_t uncompLenAndSchemaVersion = (attrDesc.fAnchorUncompLen << 16 ) | attrDesc.fSchemaVersion ;
1840+
1841+ auto frame = pos;
1842+ pos += RNTupleSerializer::SerializeRecordFramePreamble (*where);
1843+ pos += SerializeUInt64 (uncompLenAndSchemaVersion, *where);
1844+ if (auto res = SerializeLocator (attrDesc.fLocator , *where)) {
1845+ pos += res.Unwrap ();
1846+ } else {
1847+ return R__FORWARD_ERROR (res);
1848+ }
1849+ pos += SerializeString (attrDesc.fName , *where);
1850+ auto size = pos - frame;
1851+ if (auto res = SerializeFramePostscript (buffer ? frame : nullptr , size)) {
1852+ return size;
1853+ } else {
1854+ return R__FORWARD_ERROR (res);
1855+ }
1856+ }
1857+
18111858ROOT::RResult<void > ROOT::Internal::RNTupleSerializer::DeserializeHeader (const void *buffer, std::uint64_t bufSize,
18121859 RNTupleDescriptorBuilder &descBuilder)
18131860{
@@ -1918,36 +1965,95 @@ ROOT::RResult<void> ROOT::Internal::RNTupleSerializer::DeserializeFooter(const v
19181965 }
19191966 bytes = frame + frameSize;
19201967
1921- std::uint32_t nClusterGroups;
1922- frame = bytes;
1923- if (auto res = DeserializeFrameHeader (bytes, fnBufSizeLeft (), frameSize, nClusterGroups)) {
1924- bytes += res.Unwrap ();
1925- } else {
1926- return R__FORWARD_ERROR (res);
1927- }
1928- for (std::uint32_t groupId = 0 ; groupId < nClusterGroups; ++groupId) {
1929- RClusterGroup clusterGroup;
1930- if (auto res = DeserializeClusterGroup (bytes, fnFrameSizeLeft (), clusterGroup)) {
1968+ {
1969+ std::uint32_t nClusterGroups;
1970+ frame = bytes;
1971+ if (auto res = DeserializeFrameHeader (bytes, fnBufSizeLeft (), frameSize, nClusterGroups)) {
19311972 bytes += res.Unwrap ();
19321973 } else {
19331974 return R__FORWARD_ERROR (res);
19341975 }
1976+ for (std::uint32_t groupId = 0 ; groupId < nClusterGroups; ++groupId) {
1977+ RClusterGroup clusterGroup;
1978+ if (auto res = DeserializeClusterGroup (bytes, fnFrameSizeLeft (), clusterGroup)) {
1979+ bytes += res.Unwrap ();
1980+ } else {
1981+ return R__FORWARD_ERROR (res);
1982+ }
19351983
1936- descBuilder.AddToOnDiskFooterSize (clusterGroup.fPageListEnvelopeLink .fLocator .GetNBytesOnStorage ());
1937- RClusterGroupDescriptorBuilder clusterGroupBuilder;
1938- clusterGroupBuilder.ClusterGroupId (groupId)
1939- .PageListLocator (clusterGroup.fPageListEnvelopeLink .fLocator )
1940- .PageListLength (clusterGroup.fPageListEnvelopeLink .fLength )
1941- .MinEntry (clusterGroup.fMinEntry )
1942- .EntrySpan (clusterGroup.fEntrySpan )
1943- .NClusters (clusterGroup.fNClusters );
1944- descBuilder.AddClusterGroup (clusterGroupBuilder.MoveDescriptor ().Unwrap ());
1984+ descBuilder.AddToOnDiskFooterSize (clusterGroup.fPageListEnvelopeLink .fLocator .GetNBytesOnStorage ());
1985+ RClusterGroupDescriptorBuilder clusterGroupBuilder;
1986+ clusterGroupBuilder.ClusterGroupId (groupId)
1987+ .PageListLocator (clusterGroup.fPageListEnvelopeLink .fLocator )
1988+ .PageListLength (clusterGroup.fPageListEnvelopeLink .fLength )
1989+ .MinEntry (clusterGroup.fMinEntry )
1990+ .EntrySpan (clusterGroup.fEntrySpan )
1991+ .NClusters (clusterGroup.fNClusters );
1992+ descBuilder.AddClusterGroup (clusterGroupBuilder.MoveDescriptor ().Unwrap ());
1993+ }
1994+ bytes = frame + frameSize;
1995+ }
1996+
1997+ // NOTE: Attributes were introduced in v1.0.1.0, so this section may be missing.
1998+ // Testing for > 8 because bufSize includes the checksum.
1999+ if (fnBufSizeLeft () > 8 ) {
2000+ std::uint32_t nAttributeSets;
2001+ frame = bytes;
2002+ if (auto res = DeserializeFrameHeader (bytes, fnBufSizeLeft (), frameSize, nAttributeSets)) {
2003+ bytes += res.Unwrap ();
2004+ } else {
2005+ return R__FORWARD_ERROR (res);
2006+ }
2007+ for (std::uint32_t attrSetId = 0 ; attrSetId < nAttributeSets; ++attrSetId) {
2008+ Experimental::Internal::RNTupleAttrSetDescriptor attrSetDesc;
2009+ if (auto res = DeserializeAttributeSet (bytes, fnBufSizeLeft (), attrSetDesc)) {
2010+ descBuilder.AddAttributeSet (std::move (attrSetDesc));
2011+ bytes += res.Unwrap ();
2012+ } else {
2013+ return R__FORWARD_ERROR (res);
2014+ }
2015+ }
2016+ bytes = frame + frameSize;
19452017 }
1946- bytes = frame + frameSize;
19472018
19482019 return RResult<void >::Success ();
19492020}
19502021
2022+ ROOT::RResult<std::uint32_t > ROOT::Internal::RNTupleSerializer::DeserializeAttributeSet (
2023+ const void *buffer, std::uint64_t bufSize, Experimental::Internal::RNTupleAttrSetDescriptor &attrSetDesc)
2024+ {
2025+ auto base = reinterpret_cast <const unsigned char *>(buffer);
2026+ auto bytes = base;
2027+ auto fnBufSizeLeft = [&]() { return bufSize - (bytes - base); };
2028+
2029+ std::uint64_t frameSize;
2030+ if (auto res = DeserializeFrameHeader (bytes, fnBufSizeLeft (), frameSize)) {
2031+ bytes += res.Unwrap ();
2032+ } else {
2033+ return R__FORWARD_ERROR (res);
2034+ }
2035+ std::uint64_t uncompLenAndSchemaVersion;
2036+ bytes += DeserializeUInt64 (bytes, uncompLenAndSchemaVersion);
2037+ std::uint64_t uncompLen = uncompLenAndSchemaVersion >> 16 ;
2038+ std::uint16_t schemaVersion = uncompLenAndSchemaVersion & 0xF ;
2039+ RNTupleLocator attrSetLocator;
2040+ if (auto res = DeserializeLocator (bytes, fnBufSizeLeft (), attrSetLocator)) {
2041+ bytes += res.Unwrap ();
2042+ } else {
2043+ return R__FORWARD_ERROR (res);
2044+ }
2045+ std::string attrSetName;
2046+ if (auto res = DeserializeString (bytes, fnBufSizeLeft (), attrSetName)) {
2047+ bytes += res.Unwrap ();
2048+ } else {
2049+ return R__FORWARD_ERROR (res);
2050+ }
2051+
2052+ attrSetDesc = {uncompLen, schemaVersion, attrSetLocator, attrSetName};
2053+
2054+ return frameSize;
2055+ }
2056+
19512057ROOT::RResult<std::vector<ROOT::Internal::RClusterDescriptorBuilder>>
19522058ROOT::Internal::RNTupleSerializer::DeserializePageListRaw (const void *buffer, std::uint64_t bufSize,
19532059 ROOT::DescriptorId_t clusterGroupId,
0 commit comments