40#ifndef R__LITTLE_ENDIAN
43#define R__LITTLE_ENDIAN 1
45#define R__LITTLE_ENDIAN 0
56 std::uint16_t fValBE = 0;
57 static std::uint16_t
Swap(std::uint16_t val)
59#if R__LITTLE_ENDIAN == 1
60 return RByteSwap<
sizeof(val)>::bswap(val);
67 RUInt16BE() =
default;
68 explicit RUInt16BE(
const std::uint16_t val) : fValBE(
Swap(val)) {}
69 operator std::uint16_t()
const {
return Swap(fValBE); }
70 RUInt16BE &
operator=(
const std::uint16_t val)
80 std::uint32_t fValBE = 0;
81 static std::uint32_t
Swap(std::uint32_t val)
83#if R__LITTLE_ENDIAN == 1
84 return RByteSwap<
sizeof(val)>::bswap(val);
91 RUInt32BE() =
default;
92 explicit RUInt32BE(
const std::uint32_t val) : fValBE(
Swap(val)) {}
93 operator std::uint32_t()
const {
return Swap(fValBE); }
94 RUInt32BE &
operator=(
const std::uint32_t val)
104 std::int32_t fValBE = 0;
105 static std::int32_t
Swap(std::int32_t val)
107#if R__LITTLE_ENDIAN == 1
108 return RByteSwap<
sizeof(val)>::bswap(val);
115 RInt32BE() =
default;
116 explicit RInt32BE(
const std::int32_t val) : fValBE(
Swap(val)) {}
117 operator std::int32_t()
const {
return Swap(fValBE); }
118 RInt32BE &
operator=(
const std::int32_t val)
128 std::uint64_t fValBE = 0;
129 static std::uint64_t
Swap(std::uint64_t val)
131#if R__LITTLE_ENDIAN == 1
132 return RByteSwap<
sizeof(val)>::bswap(val);
139 RUInt64BE() =
default;
140 explicit RUInt64BE(
const std::uint64_t val) : fValBE(
Swap(val)) {}
141 operator std::uint64_t()
const {
return Swap(fValBE); }
142 RUInt64BE &
operator=(
const std::uint64_t val)
149constexpr std::int32_t ChecksumRNTupleClass()
151 const char ident[] =
"ROOT::Experimental::RNTuple"
173 for (
unsigned i = 0; i < (
sizeof(ident) - 1); i++)
174 id =
static_cast<std::int32_t
>(
static_cast<std::int64_t
>(
id) * 3 + ident[i]);
181 unsigned char fLName{0};
183 RTFString() =
default;
184 RTFString(
const std::string &str)
189 fLName = str.length();
190 memcpy(fData, str.data(), fLName);
192 std::size_t GetSize()
const
206 auto now = std::chrono::system_clock::now();
207 auto tt = std::chrono::system_clock::to_time_t(now);
208 auto tm = *localtime(&
tt);
209 fDatetime = (tm.tm_year + 1900 - 1995) << 26 | (tm.tm_mon + 1) << 22 | tm.tm_mday << 17 | tm.tm_hour << 12 |
210 tm.tm_min << 6 | tm.tm_sec;
212 explicit RTFDatetime(RUInt32BE val) : fDatetime(val) {}
218 RUInt16BE fVersion{4};
219 RUInt32BE fObjLen{0};
220 RTFDatetime fDatetime;
221 RUInt16BE fKeyLen{0};
225 RUInt32BE fSeekKey{0};
226 RUInt32BE fSeekPdir{0};
229 RUInt64BE fSeekKey{0};
230 RUInt64BE fSeekPdir{0};
234 std::uint32_t fKeyHeaderSize{18 +
sizeof(fInfoShort)};
236 RTFKey() : fInfoShort() {}
237 RTFKey(std::uint64_t seekKey, std::uint64_t seekPdir,
const RTFString &clName,
const RTFString &objName,
238 const RTFString &titleName, std::size_t szObjInMem, std::size_t szObjOnDisk = 0)
240 R__ASSERT(szObjInMem < std::numeric_limits<std::int32_t>::max());
241 R__ASSERT(szObjOnDisk < std::numeric_limits<std::int32_t>::max());
242 fObjLen = szObjInMem;
243 if ((seekKey >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) ||
244 (seekPdir >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max()))) {
245 fKeyHeaderSize = 18 +
sizeof(fInfoLong);
246 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
247 fInfoLong.fSeekKey = seekKey;
248 fInfoLong.fSeekPdir = seekPdir;
249 fVersion = fVersion + 1000;
251 fKeyHeaderSize = 18 +
sizeof(fInfoShort);
252 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
253 fInfoShort.fSeekKey = seekKey;
254 fInfoShort.fSeekPdir = seekPdir;
256 fNbytes = fKeyLen + ((szObjOnDisk == 0) ? szObjInMem : szObjOnDisk);
261 if (fVersion >= 1000)
263 std::uint32_t seekKey = fInfoShort.fSeekKey;
264 std::uint32_t seekPdir = fInfoShort.fSeekPdir;
265 fInfoLong.fSeekKey = seekKey;
266 fInfoLong.fSeekPdir = seekPdir;
267 fKeyHeaderSize = fKeyHeaderSize +
sizeof(fInfoLong) -
sizeof(fInfoShort);
268 fKeyLen = fKeyLen +
sizeof(fInfoLong) -
sizeof(fInfoShort);
269 fNbytes = fNbytes +
sizeof(fInfoLong) -
sizeof(fInfoShort);
270 fVersion = fVersion + 1000;
273 std::uint32_t GetSize()
const
281 std::uint32_t GetHeaderSize()
const
283 if (fVersion >= 1000)
284 return 18 +
sizeof(fInfoLong);
285 return 18 +
sizeof(fInfoShort);
288 std::uint64_t GetSeekKey()
const
290 if (fVersion >= 1000)
291 return fInfoLong.fSeekKey;
292 return fInfoShort.fSeekKey;
298 char fMagic[4]{
'r',
'o',
'o',
't'};
301 RUInt32BE fBEGIN{100};
305 RUInt32BE fSeekFree{0};
306 RUInt32BE fNbytesFree{0};
308 RUInt32BE fNbytesName{0};
309 unsigned char fUnits{4};
310 RUInt32BE fCompress{0};
311 RUInt32BE fSeekInfo{0};
312 RUInt32BE fNbytesInfo{0};
316 RUInt64BE fSeekFree{0};
317 RUInt32BE fNbytesFree{0};
319 RUInt32BE fNbytesName{0};
320 unsigned char fUnits{8};
321 RUInt32BE fCompress{0};
322 RUInt64BE fSeekInfo{0};
323 RUInt32BE fNbytesInfo{0};
327 RTFHeader() : fInfoShort() {}
328 RTFHeader(
int compression) : fInfoShort() { fInfoShort.fCompress = compression; }
332 if (fVersion >= 1000000)
336 std::uint32_t end = fInfoShort.fEND;
337 std::uint32_t seekFree = fInfoShort.fSeekFree;
338 std::uint32_t nbytesFree = fInfoShort.fNbytesFree;
339 std::uint32_t nFree = fInfoShort.fNfree;
340 std::uint32_t nbytesName = fInfoShort.fNbytesName;
341 std::uint32_t compress = fInfoShort.fCompress;
342 std::uint32_t seekInfo = fInfoShort.fSeekInfo;
343 std::uint32_t nbytesInfo = fInfoShort.fNbytesInfo;
344 fInfoLong.fEND = end;
345 fInfoLong.fSeekFree = seekFree;
346 fInfoLong.fNbytesFree = nbytesFree;
347 fInfoLong.fNfree = nFree;
348 fInfoLong.fNbytesName = nbytesName;
349 fInfoLong.fUnits = 8;
350 fInfoLong.fCompress = compress;
351 fInfoLong.fSeekInfo = seekInfo;
352 fInfoLong.fNbytesInfo = nbytesInfo;
353 fVersion = fVersion + 1000000;
357 bool IsBigFile(std::uint64_t
offset = 0)
const
359 return (fVersion >= 1000000) || (
offset >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max()));
362 std::uint32_t GetSize()
const
364 std::uint32_t sizeHead = 4 +
sizeof(fVersion) +
sizeof(fBEGIN);
366 return sizeHead +
sizeof(fInfoLong);
367 return sizeHead +
sizeof(fInfoShort);
370 std::uint64_t GetEnd()
const
373 return fInfoLong.fEND;
374 return fInfoShort.fEND;
377 void SetEnd(std::uint64_t
value)
379 if (IsBigFile(
value)) {
381 fInfoLong.fEND =
value;
383 fInfoShort.fEND =
value;
387 std::uint64_t GetSeekFree()
const
390 return fInfoLong.fSeekFree;
391 return fInfoShort.fSeekFree;
394 void SetSeekFree(std::uint64_t
value)
396 if (IsBigFile(
value)) {
398 fInfoLong.fSeekFree =
value;
400 fInfoShort.fSeekFree =
value;
404 void SetNbytesFree(std::uint32_t
value)
407 fInfoLong.fNbytesFree =
value;
409 fInfoShort.fNbytesFree =
value;
413 void SetNbytesName(std::uint32_t
value)
416 fInfoLong.fNbytesName =
value;
418 fInfoShort.fNbytesName =
value;
422 std::uint64_t GetSeekInfo()
const
425 return fInfoLong.fSeekInfo;
426 return fInfoShort.fSeekInfo;
429 void SetSeekInfo(std::uint64_t
value)
431 if (IsBigFile(
value)) {
433 fInfoLong.fSeekInfo =
value;
435 fInfoShort.fSeekInfo =
value;
439 void SetNbytesInfo(std::uint32_t
value)
442 fInfoLong.fNbytesInfo =
value;
444 fInfoShort.fNbytesInfo =
value;
448 void SetCompression(std::uint32_t
value)
451 fInfoLong.fCompress =
value;
453 fInfoShort.fCompress =
value;
460 RUInt16BE fVersion{1};
472 RTFFreeEntry() : fInfoShort() {}
473 void Set(std::uint64_t first, std::uint64_t last)
475 if (last >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) {
476 fVersion = fVersion + 1000;
477 fInfoLong.fFirst = first;
478 fInfoLong.fLast = last;
480 fInfoShort.fFirst = first;
481 fInfoShort.fLast = last;
484 std::uint32_t GetSize() {
return (fVersion >= 1000) ? 18 : 10; }
489 RUInt16BE fVersion{1};
490 RUInt32BE fUniqueID{0};
492 explicit RTFObject(std::uint32_t bits) : fBits(bits) {}
496struct RTFStreamerElementVersionEpoch {
497 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionEpoch) -
sizeof(RUInt32BE))};
498 RUInt16BE fVersion{4};
500 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
501 RUInt16BE fVersionNamed{1};
502 RTFObject fObjectNamed{0x02000000 | 0x01000000};
504 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'E',
'p',
'o',
'c',
'h'};
509 RUInt32BE fArrLength{0};
510 RUInt32BE fArrDim{0};
511 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
512 char fLTypeName = 14;
513 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
517struct RTFStreamerElementVersionMajor {
518 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionMajor) -
sizeof(RUInt32BE))};
519 RUInt16BE fVersion{4};
521 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
522 RUInt16BE fVersionNamed{1};
523 RTFObject fObjectNamed{0x02000000 | 0x01000000};
525 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'M',
'a',
'j',
'o',
'r'};
530 RUInt32BE fArrLength{0};
531 RUInt32BE fArrDim{0};
532 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
533 char fLTypeName = 14;
534 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
538struct RTFStreamerElementVersionMinor {
539 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionMinor) -
sizeof(RUInt32BE))};
540 RUInt16BE fVersion{4};
542 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
543 RUInt16BE fVersionNamed{1};
544 RTFObject fObjectNamed{0x02000000 | 0x01000000};
546 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'M',
'i',
'n',
'o',
'r'};
551 RUInt32BE fArrLength{0};
552 RUInt32BE fArrDim{0};
553 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
554 char fLTypeName = 14;
555 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
559struct RTFStreamerElementVersionPatch {
560 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionPatch) -
sizeof(RUInt32BE))};
561 RUInt16BE fVersion{4};
563 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
564 RUInt16BE fVersionNamed{1};
565 RTFObject fObjectNamed{0x02000000 | 0x01000000};
567 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'P',
'a',
't',
'c',
'h'};
572 RUInt32BE fArrLength{0};
573 RUInt32BE fArrDim{0};
574 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
575 char fLTypeName = 14;
576 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
580struct RTFStreamerElementSeekHeader {
581 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekHeader) -
sizeof(RUInt32BE))};
582 RUInt16BE fVersion{4};
584 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
585 RUInt16BE fVersionNamed{1};
586 RTFObject fObjectNamed{0x02000000 | 0x01000000};
588 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'H',
'e',
'a',
'd',
'e',
'r'};
593 RUInt32BE fArrLength{0};
594 RUInt32BE fArrDim{0};
595 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
596 char fLTypeName = 13;
597 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
601struct RTFStreamerElementNBytesHeader {
602 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesHeader) -
sizeof(RUInt32BE))};
603 RUInt16BE fVersion{4};
605 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
606 RUInt16BE fVersionNamed{1};
607 RTFObject fObjectNamed{0x02000000 | 0x01000000};
609 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'H',
'e',
'a',
'd',
'e',
'r'};
614 RUInt32BE fArrLength{0};
615 RUInt32BE fArrDim{0};
616 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
617 char fLTypeName = 13;
618 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
622struct RTFStreamerElementLenHeader {
623 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenHeader) -
sizeof(RUInt32BE))};
624 RUInt16BE fVersion{4};
626 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
627 RUInt16BE fVersionNamed{1};
628 RTFObject fObjectNamed{0x02000000 | 0x01000000};
630 char fName[10]{
'f',
'L',
'e',
'n',
'H',
'e',
'a',
'd',
'e',
'r'};
635 RUInt32BE fArrLength{0};
636 RUInt32BE fArrDim{0};
637 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
638 char fLTypeName = 13;
639 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
643struct RTFStreamerElementSeekFooter {
644 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekFooter) -
sizeof(RUInt32BE))};
645 RUInt16BE fVersion{4};
647 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
648 RUInt16BE fVersionNamed{1};
649 RTFObject fObjectNamed{0x02000000 | 0x01000000};
651 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'F',
'o',
'o',
't',
'e',
'r'};
656 RUInt32BE fArrLength{0};
657 RUInt32BE fArrDim{0};
658 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
659 char fLTypeName = 13;
660 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
664struct RTFStreamerElementNBytesFooter {
665 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesFooter) -
sizeof(RUInt32BE))};
666 RUInt16BE fVersion{4};
668 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
669 RUInt16BE fVersionNamed{1};
670 RTFObject fObjectNamed{0x02000000 | 0x01000000};
672 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'F',
'o',
'o',
't',
'e',
'r'};
677 RUInt32BE fArrLength{0};
678 RUInt32BE fArrDim{0};
679 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
680 char fLTypeName = 13;
681 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
685struct RTFStreamerElementLenFooter {
686 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenFooter) -
sizeof(RUInt32BE))};
687 RUInt16BE fVersion{4};
689 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
690 RUInt16BE fVersionNamed{1};
691 RTFObject fObjectNamed{0x02000000 | 0x01000000};
693 char fName[10]{
'f',
'L',
'e',
'n',
'F',
'o',
'o',
't',
'e',
'r'};
698 RUInt32BE fArrLength{0};
699 RUInt32BE fArrDim{0};
700 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
701 char fLTypeName = 13;
702 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
705struct RTFStreamerElementMaxKeySize {
706 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementMaxKeySize) -
sizeof(RUInt32BE))};
707 RUInt16BE fVersion{4};
709 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
710 RUInt16BE fVersionNamed{1};
711 RTFObject fObjectNamed{0x02000000 | 0x01000000};
713 char fName[11]{
'f',
'M',
'a',
'x',
'K',
'e',
'y',
'S',
'i',
'z',
'e'};
718 RUInt32BE fArrLength{0};
719 RUInt32BE fArrDim{0};
720 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
721 char fLTypeName = 13;
722 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
726struct RTFStreamerVersionEpoch {
727 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionEpoch) -
sizeof(RUInt32BE))};
728 RUInt32BE fNewClassTag{0xffffffff};
729 char fClassName[19]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'B',
'a',
's',
'i',
'c',
'T',
'y',
'p',
'e',
'\0'};
730 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionEpoch) - 2 *
sizeof(RUInt32BE) -
731 19 -
sizeof(RUInt32BE))};
732 RUInt16BE fVersion{2};
733 RTFStreamerElementVersionEpoch fStreamerElementVersionEpoch;
737struct RTFStreamerVersionMajor {
738 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionMajor) -
sizeof(RUInt32BE))};
739 RUInt32BE fClassTag{0x80000000};
740 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionMajor) - 3 *
sizeof(RUInt32BE))};
741 RUInt16BE fVersion{2};
742 RTFStreamerElementVersionMajor fStreamerElementVersionMajor;
746struct RTFStreamerVersionMinor {
747 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionMinor) -
sizeof(RUInt32BE))};
748 RUInt32BE fClassTag{0x80000000};
749 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionMinor) - 3 *
sizeof(RUInt32BE))};
750 RUInt16BE fVersion{2};
751 RTFStreamerElementVersionMinor fStreamerElementVersionMinor;
755struct RTFStreamerVersionPatch {
756 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionPatch) -
sizeof(RUInt32BE))};
757 RUInt32BE fClassTag{0x80000000};
758 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionPatch) - 3 *
sizeof(RUInt32BE))};
759 RUInt16BE fVersion{2};
760 RTFStreamerElementVersionPatch fStreamerElementVersionPatch;
764struct RTFStreamerSeekHeader {
765 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekHeader) -
sizeof(RUInt32BE))};
766 RUInt32BE fClassTag{0x80000000};
767 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekHeader) - 3 *
sizeof(RUInt32BE))};
768 RUInt16BE fVersion{2};
769 RTFStreamerElementSeekHeader fStreamerElementSeekHeader;
773struct RTFStreamerNBytesHeader {
774 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) -
sizeof(RUInt32BE))};
775 RUInt32BE fClassTag{0x80000000};
776 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) - 3 *
sizeof(RUInt32BE))};
777 RUInt16BE fVersion{2};
778 RTFStreamerElementNBytesHeader fStreamerElementNBytesHeader;
782struct RTFStreamerLenHeader {
783 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenHeader) -
sizeof(RUInt32BE))};
784 RUInt32BE fClassTag{0x80000000};
785 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenHeader) - 3 *
sizeof(RUInt32BE))};
786 RUInt16BE fVersion{2};
787 RTFStreamerElementLenHeader fStreamerElementLenHeader;
791struct RTFStreamerSeekFooter {
792 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekFooter) -
sizeof(RUInt32BE))};
793 RUInt32BE fClassTag{0x80000000};
794 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekFooter) - 3 *
sizeof(RUInt32BE))};
795 RUInt16BE fVersion{2};
796 RTFStreamerElementSeekFooter fStreamerElementSeekFooter;
800struct RTFStreamerNBytesFooter {
801 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) -
sizeof(RUInt32BE))};
802 RUInt32BE fClassTag{0x80000000};
803 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) - 3 *
sizeof(RUInt32BE))};
804 RUInt16BE fVersion{2};
805 RTFStreamerElementNBytesFooter fStreamerElementNBytesFooter;
809struct RTFStreamerLenFooter {
810 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenFooter) -
sizeof(RUInt32BE))};
811 RUInt32BE fClassTag{0x80000000};
812 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenFooter) - 3 *
sizeof(RUInt32BE))};
813 RUInt16BE fVersion{2};
814 RTFStreamerElementLenFooter fStreamerElementLenFooter;
818struct RTFStreamerMaxKeySize {
819 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerMaxKeySize) -
sizeof(RUInt32BE))};
820 RUInt32BE fClassTag{0x80000000};
821 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerMaxKeySize) - 3 *
sizeof(RUInt32BE))};
822 RUInt16BE fVersion{2};
823 RTFStreamerElementMaxKeySize fStreamerElementMaxKeySize;
827struct RTFStreamerInfoObject {
828 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoObject) -
sizeof(fByteCount))};
829 RUInt32BE fNewClassTag{0xffffffff};
830 char fClassName[14]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'I',
'n',
'f',
'o',
'\0'};
831 RUInt32BE fByteCountRemaining{0x40000000 |
832 (
sizeof(RTFStreamerInfoObject) - 2 *
sizeof(RUInt32BE) - 14 -
sizeof(RUInt32BE))};
833 RUInt16BE fVersion{9};
835 RUInt32BE fByteCountNamed{
836 0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 29 )};
837 RUInt16BE fVersionNamed{1};
838 RTFObject fObjectNamed{0x02000000 | 0x01000000 | 0x00010000};
840 char fName[27]{
'R',
'O',
'O',
'T',
':',
':',
'E',
'x',
'p',
'e',
'r',
'i',
'm',
'e',
841 'n',
't',
'a',
'l',
':',
':',
'R',
'N',
'T',
'u',
'p',
'l',
'e'};
844 RInt32BE fChecksum{ChecksumRNTupleClass()};
846 RUInt32BE fVersionRNTuple{6};
848 RUInt32BE fByteCountObjArr{0x40000000 |
849 (
sizeof(RUInt32BE) + 10 +
sizeof(RUInt32BE) +
850 sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2 *
sizeof(RUInt32BE) +
sizeof(fStreamers))};
851 RUInt32BE fNewClassTagObjArray{0xffffffff};
852 char fClassNameObjArray[10]{
'T',
'O',
'b',
'j',
'A',
'r',
'r',
'a',
'y',
'\0'};
853 RUInt32BE fByteCountObjArrRemaining{
854 0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2 *
sizeof(RUInt32BE) +
sizeof(fStreamers))};
855 RUInt16BE fVersionObjArr{3};
856 RTFObject fObjectObjArr{0x02000000};
859 RUInt32BE fNObjects{11};
860 RUInt32BE fLowerBound{0};
863 RTFStreamerVersionEpoch fStreamerVersionEpoch;
864 RTFStreamerVersionMajor fStreamerVersionMajor;
865 RTFStreamerVersionMinor fStreamerVersionMinor;
866 RTFStreamerVersionPatch fStreamerVersionPatch;
867 RTFStreamerSeekHeader fStreamerSeekHeader;
868 RTFStreamerNBytesHeader fStreamerNBytesHeader;
869 RTFStreamerLenHeader fStreamerLenHeader;
870 RTFStreamerSeekFooter fStreamerSeekFooter;
871 RTFStreamerNBytesFooter fStreamerNBytesFooter;
872 RTFStreamerLenFooter fStreamerLenFooter;
873 RTFStreamerMaxKeySize fStreamerMaxKeySize;
878struct RTFStreamerInfoList {
879 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoList) -
sizeof(fByteCount))};
880 RUInt16BE fVersion{5};
881 RTFObject fObject{0x02000000};
883 RUInt32BE fNObjects{1};
884 RTFStreamerInfoObject fStreamerInfo;
887 std::uint32_t GetSize()
const {
return sizeof(RTFStreamerInfoList); }
893 std::uint32_t GetSize()
const {
return sizeof(RTFKeyList); }
894 explicit RTFKeyList(std::uint32_t nKeys) : fNKeys(nKeys) {}
899 RUInt16BE fClassVersion{5};
902 RUInt32BE fNBytesKeys{0};
903 RUInt32BE fNBytesName{0};
907 RUInt32BE fSeekDir{100};
908 RUInt32BE fSeekParent{0};
909 RUInt32BE fSeekKeys{0};
912 RUInt64BE fSeekDir{100};
913 RUInt64BE fSeekParent{0};
914 RUInt64BE fSeekKeys{0};
918 RTFFile() : fInfoShort() {}
921 std::uint32_t GetSize()
const
923 if (fClassVersion >= 1000)
924 return sizeof(RTFFile);
925 return 18 +
sizeof(fInfoShort);
928 std::uint64_t GetSeekKeys()
const
930 if (fClassVersion >= 1000)
931 return fInfoLong.fSeekKeys;
932 return fInfoShort.fSeekKeys;
935 void SetSeekKeys(std::uint64_t seekKeys)
937 if (seekKeys >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) {
938 std::uint32_t seekDir = fInfoShort.fSeekDir;
939 std::uint32_t seekParent = fInfoShort.fSeekParent;
940 fInfoLong.fSeekDir = seekDir;
941 fInfoLong.fSeekParent = seekParent;
942 fInfoLong.fSeekKeys = seekKeys;
943 fClassVersion = fClassVersion + 1000;
945 fInfoShort.fSeekKeys = seekKeys;
952 RUInt16BE fVersionClass{1};
953 unsigned char fUUID[16] = {0};
956 std::uint32_t GetSize()
const {
return sizeof(RTFUUID); }
965 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFNTuple) -
sizeof(fByteCount))};
966 RUInt16BE fVersionClass{6};
967 RUInt16BE fVersionEpoch{0};
968 RUInt16BE fVersionMajor{0};
969 RUInt16BE fVersionMinor{0};
970 RUInt16BE fVersionPatch{0};
971 RUInt64BE fSeekHeader{0};
972 RUInt64BE fNBytesHeader{0};
973 RUInt64BE fLenHeader{0};
974 RUInt64BE fSeekFooter{0};
975 RUInt64BE fNBytesFooter{0};
976 RUInt64BE fLenFooter{0};
977 RUInt64BE fMaxKeySize{0};
979 static constexpr std::uint32_t GetSizePlusChecksum() {
return sizeof(RTFNTuple) +
sizeof(std::uint64_t); }
981 RTFNTuple() =
default;
996 std::uint32_t GetSize()
const {
return sizeof(RTFNTuple); }
998 std::uint32_t GetOffsetCkData() {
return sizeof(fByteCount) +
sizeof(fVersionClass); }
999 std::uint32_t GetSizeCkData() {
return GetSize() - GetOffsetCkData(); }
1000 unsigned char *GetPtrCkData() {
return reinterpret_cast<unsigned char *
>(
this) + GetOffsetCkData(); }
1004struct RBareFileHeader {
1005 char fMagic[7]{
'r',
'n',
't',
'u',
'p',
'l',
'e'};
1008 RUInt32BE fFormatVersion{1};
1009 RUInt32BE fCompress{0};
1016constexpr char const *kBlobClassName =
"RBlob";
1018constexpr char const *kNTupleClassName =
"ROOT::Experimental::RNTuple";
1023namespace Experimental {
1050 void Reserve(
size_t nbytes, std::uint64_t *seekKey)
1066 std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor, std::uint16_t versionPatch,
1067 std::uint64_t seekHeader, std::uint64_t nbytesHeader, std::uint64_t lenHeader, std::uint64_t seekFooter,
1068 std::uint64_t nbytesFooter, std::uint64_t lenFooter, std::uint64_t maxKeySize)
1090 if (std::string(ident, 4) ==
"root")
1091 return GetNTupleProper(ntupleName);
1093 return GetNTupleBare(ntupleName);
1099 RTFHeader fileHeader;
1100 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
1104 ReadBuffer(&key,
sizeof(key), fileHeader.fBEGIN);
1106 std::uint64_t
offset = fileHeader.fBEGIN + key.fKeyLen;
1116 offset = file.GetSeekKeys();
1122 for (
unsigned int i = 0; i < nKeys; ++i) {
1124 auto offsetNextKey =
offset + key.fKeyLen;
1126 offset += key.GetHeaderSize();
1129 if (std::string_view(
name.fData,
name.fLName) != kNTupleClassName) {
1136 if (std::string_view(
name.fData,
name.fLName) == ntupleName) {
1143 return R__FAIL(
"no RNTuple named '" + std::string(ntupleName) +
"' in file '" + fRawFile->GetUrl() +
"'");
1146 offset = key.GetSeekKey() + key.fKeyLen;
1148 if (key.fObjLen <
sizeof(RTFNTuple)) {
1149 return R__FAIL(
"invalid anchor size: " + std::to_string(key.fObjLen) +
" < " + std::to_string(
sizeof(RTFNTuple)));
1152 auto bufAnchor = std::make_unique<unsigned char[]>(key.fObjLen);
1153 RTFNTuple *ntuple =
new (bufAnchor.get()) RTFNTuple;
1155 auto objNbytes = key.GetSize() - key.fKeyLen;
1157 if (objNbytes != key.fObjLen) {
1159 decompressor.
Unzip(bufAnchor.get(), objNbytes, key.fObjLen);
1162 if (ntuple->fVersionClass < 4) {
1163 return R__FAIL(
"invalid anchor, unsupported pre-release of RNTuple");
1168 RUInt64BE *ckOnDisk =
reinterpret_cast<RUInt64BE *
>(bufAnchor.get() + key.fObjLen -
sizeof(uint64_t));
1169 auto lenCkData = key.fObjLen - ntuple->GetOffsetCkData() -
sizeof(uint64_t);
1170 auto ckCalc = XXH3_64bits(ntuple->GetPtrCkData(), lenCkData);
1171 if (ckCalc != (uint64_t)(*ckOnDisk)) {
1172 return R__FAIL(
"RNTuple anchor checksum mismatch");
1175 return CreateAnchor(ntuple->fVersionEpoch, ntuple->fVersionMajor, ntuple->fVersionMinor, ntuple->fVersionPatch,
1176 ntuple->fSeekHeader, ntuple->fNBytesHeader, ntuple->fLenHeader, ntuple->fSeekFooter,
1177 ntuple->fNBytesFooter, ntuple->fLenFooter, ntuple->fMaxKeySize);
1183 RBareFileHeader fileHeader;
1184 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
1186 auto offset =
sizeof(fileHeader);
1189 std::string_view foundName(
name.fData,
name.fLName);
1190 if (foundName != ntupleName) {
1191 return R__FAIL(
"expected RNTuple named '" + std::string(ntupleName) +
"' but instead found '" +
1192 std::string(foundName) +
"' in file '" + fRawFile->GetUrl() +
"'");
1198 std::uint64_t onDiskChecksum;
1199 ReadBuffer(&onDiskChecksum,
sizeof(onDiskChecksum),
offset +
sizeof(ntuple));
1200 auto checksum = XXH3_64bits(ntuple.GetPtrCkData(), ntuple.GetSizeCkData());
1201 if (checksum !=
static_cast<uint64_t
>(onDiskChecksum))
1202 return R__FAIL(
"RNTuple bare file: anchor checksum mismatch");
1203 return CreateAnchor(ntuple.fVersionEpoch, ntuple.fVersionMajor, ntuple.fVersionMinor, ntuple.fVersionPatch,
1204 ntuple.fSeekHeader, ntuple.fNBytesHeader, ntuple.fLenHeader, ntuple.fSeekFooter,
1205 ntuple.fNBytesFooter, ntuple.fLenFooter, ntuple.fMaxKeySize);
1210 auto nread = fRawFile->ReadAt(buffer, nbytes,
offset);
1227 if ((
offset >= 0) && (
static_cast<std::uint64_t
>(
offset) != fFilePos)) {
1229 retval = fseeko64(fFile,
offset, SEEK_SET);
1231 retval = fseek(fFile,
offset, SEEK_SET);
1237 retval = fwrite(buffer, 1, nbytes, fFile);
1238 if (retval != nbytes)
1244 const void *buffer, std::size_t nbytes, std::size_t
len, std::int64_t
offset, std::uint64_t directoryOffset,
1245 const std::string &className,
const std::string &objectName,
const std::string &title)
1249 RTFString strClass{className};
1250 RTFString strObject{objectName};
1251 RTFString strTitle{title};
1253 RTFKey key(fKeyOffset, directoryOffset, strClass, strObject, strTitle,
len, nbytes);
1254 Write(&key, key.fKeyHeaderSize, fKeyOffset);
1255 Write(&strClass, strClass.GetSize());
1256 Write(&strObject, strObject.GetSize());
1257 Write(&strTitle, strTitle.GetSize());
1258 auto offsetData = fFilePos;
1260 fKeyOffset = offsetData + nbytes;
1262 Write(buffer, nbytes);
1274 bool rv = fFile->WriteBuffer((
char *)(buffer), nbytes);
1282 std::uint64_t offsetKey;
1286 keyBlob.
Reserve(nbytes, &offsetKey);
1289 RTFString strClass{kBlobClassName};
1290 RTFString strObject;
1292 RTFKey keyHeader(
offset,
offset, strClass, strObject, strTitle,
len, nbytes);
1294 keyHeader.MakeBigKey();
1296 Write(&keyHeader, keyHeader.fKeyHeaderSize,
offset);
1297 offset += keyHeader.fKeyHeaderSize;
1298 Write(&strClass, strClass.GetSize(),
offset);
1299 offset += strClass.GetSize();
1300 Write(&strObject, strObject.GetSize(),
offset);
1301 offset += strObject.GetSize();
1302 Write(&strTitle, strTitle.GetSize(),
offset);
1303 offset += strTitle.GetSize();
1304 auto offsetData =
offset;
1306 Write(buffer, nbytes,
offset);
1320std::unique_ptr<ROOT::Experimental::Internal::RNTupleFileWriter>
1324 std::string fileName(path);
1325 size_t idxDirSep = fileName.find_last_of(
"\\/");
1326 if (idxDirSep != std::string::npos) {
1327 fileName.erase(0, idxDirSep + 1);
1330 FILE *fileStream = fopen64(std::string(path.data(), path.size()).c_str(),
"wb");
1332 FILE *fileStream = fopen(std::string(path.data(), path.size()).c_str(),
"wb");
1337 writer->fFileSimple.fFile = fileStream;
1338 writer->fFileName = fileName;
1340 switch (containerFormat) {
1341 case EContainerFormat::kTFile:
writer->WriteTFileSkeleton(defaultCompression);
break;
1342 case EContainerFormat::kBare:
1344 writer->WriteBareFileSkeleton(defaultCompression);
1346 default:
R__ASSERT(
false &&
"Internal error: unhandled container format");
1352std::unique_ptr<ROOT::Experimental::Internal::RNTupleFileWriter>
1356 writer->fFileProper.fFile = &file;
1364 fFileProper.fFile->WriteObject(&fNTupleAnchor, fNTupleName.c_str());
1365 fFileProper.fFile->Write();
1373 RTFNTuple ntupleOnDisk(fNTupleAnchor);
1374 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize(), fFileSimple.fControlBlock->fSeekNTuple);
1376 std::uint64_t checksum = XXH3_64bits(ntupleOnDisk.GetPtrCkData(), ntupleOnDisk.GetSizeCkData());
1377 fFileSimple.Write(&checksum,
sizeof(checksum));
1378 fflush(fFileSimple.fFile);
1382 WriteTFileNTupleKey();
1383 WriteTFileKeysList();
1384 WriteTFileStreamerInfo();
1385 WriteTFileFreeList();
1388 fFileSimple.Write(&fFileSimple.fControlBlock->fHeader, fFileSimple.fControlBlock->fHeader.GetSize(), 0);
1389 fFileSimple.Write(&fFileSimple.fControlBlock->fFileRecord, fFileSimple.fControlBlock->fFileRecord.GetSize(),
1390 fFileSimple.fControlBlock->fSeekFileRecord);
1391 fflush(fFileSimple.fFile);
1399 offset = fFileSimple.fKeyOffset;
1400 fFileSimple.Write(
data, nbytes);
1401 fFileSimple.fKeyOffset += nbytes;
1403 offset = fFileSimple.WriteKey(
data, nbytes,
len, -1, 100, kBlobClassName);
1416 offset = fFileSimple.fKeyOffset;
1417 fFileSimple.fKeyOffset += nbytes;
1419 offset = fFileSimple.WriteKey(
nullptr, nbytes,
len, -1, 100, kBlobClassName);
1422 offset = fFileProper.WriteKey(
nullptr, nbytes,
len);
1431 fFileSimple.Write(buffer, nbytes,
offset);
1433 fFileProper.Write(buffer, nbytes,
offset);
1440 auto offset = WriteBlob(
data, nbytes, lenHeader);
1441 fNTupleAnchor.fLenHeader = lenHeader;
1442 fNTupleAnchor.fNBytesHeader = nbytes;
1443 fNTupleAnchor.fSeekHeader =
offset;
1450 auto offset = WriteBlob(
data, nbytes, lenFooter);
1451 fNTupleAnchor.fLenFooter = lenFooter;
1452 fNTupleAnchor.fNBytesFooter = nbytes;
1453 fNTupleAnchor.fSeekFooter =
offset;
1459 RBareFileHeader bareHeader;
1460 bareHeader.fCompress = defaultCompression;
1461 fFileSimple.Write(&bareHeader,
sizeof(bareHeader), 0);
1462 RTFString ntupleName{fNTupleName};
1463 fFileSimple.Write(&ntupleName, ntupleName.GetSize());
1466 RTFNTuple ntupleOnDisk;
1467 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fFilePos;
1468 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize());
1469 std::uint64_t checksum = 0;
1470 fFileSimple.Write(&checksum,
sizeof(checksum));
1471 fFileSimple.fKeyOffset = fFileSimple.fFilePos;
1476 RTFString strTList{
"TList"};
1477 RTFString strStreamerInfo{
"StreamerInfo"};
1478 RTFString strStreamerTitle{
"Doubly linked list"};
1480 fFileSimple.fControlBlock->fHeader.SetSeekInfo(fFileSimple.fKeyOffset);
1481 RTFKey keyStreamerInfo(fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100, strTList, strStreamerInfo,
1482 strStreamerTitle, 0);
1483 RTFStreamerInfoList streamerInfo;
1484 auto classTagOffset = keyStreamerInfo.fKeyLen + offsetof(
struct RTFStreamerInfoList, fStreamerInfo) +
1485 offsetof(
struct RTFStreamerInfoObject, fStreamers) +
1486 offsetof(
struct RTFStreamerVersionEpoch, fNewClassTag) + 2;
1487 streamerInfo.fStreamerInfo.fStreamers.fStreamerVersionMajor.fClassTag = 0x80000000 | classTagOffset;
1488 streamerInfo.fStreamerInfo.fStreamers.fStreamerVersionMinor.fClassTag = 0x80000000 | classTagOffset;
1489 streamerInfo.fStreamerInfo.fStreamers.fStreamerVersionPatch.fClassTag = 0x80000000 | classTagOffset;
1490 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekHeader.fClassTag = 0x80000000 | classTagOffset;
1491 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesHeader.fClassTag = 0x80000000 | classTagOffset;
1492 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenHeader.fClassTag = 0x80000000 | classTagOffset;
1493 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekFooter.fClassTag = 0x80000000 | classTagOffset;
1494 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesFooter.fClassTag = 0x80000000 | classTagOffset;
1495 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenFooter.fClassTag = 0x80000000 | classTagOffset;
1496 streamerInfo.fStreamerInfo.fStreamers.fStreamerMaxKeySize.fClassTag = 0x80000000 | classTagOffset;
1498 auto szStreamerInfo = compressor.
Zip(&streamerInfo, streamerInfo.GetSize(), 1);
1499 fFileSimple.WriteKey(compressor.
GetZipBuffer(), szStreamerInfo, streamerInfo.GetSize(),
1500 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100,
"TList",
"StreamerInfo",
1501 "Doubly linked list");
1502 fFileSimple.fControlBlock->fHeader.SetNbytesInfo(fFileSimple.fFilePos -
1503 fFileSimple.fControlBlock->fHeader.GetSeekInfo());
1509 RTFString strRNTupleClass{
"ROOT::Experimental::RNTuple"};
1510 RTFString strRNTupleName{fNTupleName};
1511 RTFString strFileName{fFileName};
1513 RTFKey keyRNTuple(fFileSimple.fControlBlock->fSeekNTuple, 100, strRNTupleClass, strRNTupleName, strEmpty,
1514 RTFNTuple::GetSizePlusChecksum());
1516 fFileSimple.fControlBlock->fFileRecord.SetSeekKeys(fFileSimple.fKeyOffset);
1517 RTFKeyList keyList{1};
1518 RTFKey keyKeyList(fFileSimple.fControlBlock->fFileRecord.GetSeekKeys(), 100, strEmpty, strFileName, strEmpty,
1519 keyList.GetSize() + keyRNTuple.fKeyLen);
1520 fFileSimple.Write(&keyKeyList, keyKeyList.fKeyHeaderSize, fFileSimple.fControlBlock->fFileRecord.GetSeekKeys());
1521 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1522 fFileSimple.Write(&strFileName, strFileName.GetSize());
1523 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1524 fFileSimple.Write(&keyList, keyList.GetSize());
1525 fFileSimple.Write(&keyRNTuple, keyRNTuple.fKeyHeaderSize);
1527 fFileSimple.Write(&strRNTupleClass, strRNTupleClass.GetSize());
1528 fFileSimple.Write(&strRNTupleName, strRNTupleName.GetSize());
1529 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1530 fFileSimple.fControlBlock->fFileRecord.fNBytesKeys =
1531 fFileSimple.fFilePos - fFileSimple.fControlBlock->fFileRecord.GetSeekKeys();
1532 fFileSimple.fKeyOffset = fFileSimple.fFilePos;
1537 fFileSimple.fControlBlock->fHeader.SetSeekFree(fFileSimple.fKeyOffset);
1539 RTFString strFileName{fFileName};
1540 RTFFreeEntry freeEntry;
1541 RTFKey keyFreeList(fFileSimple.fControlBlock->fHeader.GetSeekFree(), 100, strEmpty, strFileName, strEmpty,
1542 freeEntry.GetSize());
1543 std::uint64_t firstFree = fFileSimple.fControlBlock->fHeader.GetSeekFree() + keyFreeList.GetSize();
1544 freeEntry.Set(firstFree, std::max(2000000000ULL, ((firstFree / 1000000000ULL) + 1) * 1000000000ULL));
1545 fFileSimple.WriteKey(&freeEntry, freeEntry.GetSize(), freeEntry.GetSize(),
1546 fFileSimple.fControlBlock->fHeader.GetSeekFree(), 100,
"", fFileName,
"");
1547 fFileSimple.fControlBlock->fHeader.SetNbytesFree(fFileSimple.fFilePos -
1548 fFileSimple.fControlBlock->fHeader.GetSeekFree());
1549 fFileSimple.fControlBlock->fHeader.SetEnd(fFileSimple.fFilePos);
1554 RTFString strRNTupleClass{
"ROOT::Experimental::RNTuple"};
1555 RTFString strRNTupleName{fNTupleName};
1558 RTFNTuple ntupleOnDisk(fNTupleAnchor);
1559 RUInt64BE checksum{XXH3_64bits(ntupleOnDisk.GetPtrCkData(), ntupleOnDisk.GetSizeCkData())};
1560 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fKeyOffset;
1562 char keyBuf[RTFNTuple::GetSizePlusChecksum()];
1565 memcpy(keyBuf, &ntupleOnDisk,
sizeof(RTFNTuple));
1566 memcpy(keyBuf +
sizeof(RTFNTuple), &checksum,
sizeof(checksum));
1568 fFileSimple.WriteKey(keyBuf,
sizeof(keyBuf),
sizeof(keyBuf), fFileSimple.fControlBlock->fSeekNTuple, 100,
1569 "ROOT::Experimental::RNTuple", fNTupleName,
"");
1574 RTFString strTFile{
"TFile"};
1575 RTFString strFileName{fFileName};
1578 fFileSimple.fControlBlock->fHeader = RTFHeader(defaultCompression);
1583 RTFKey keyRoot(100, 0, strTFile, strFileName, strEmpty,
1584 sizeof(RTFFile) + strFileName.GetSize() + strEmpty.GetSize() + uuid.GetSize());
1585 std::uint32_t nbytesName = keyRoot.fKeyLen + strFileName.GetSize() + 1;
1586 fFileSimple.fControlBlock->fFileRecord.fNBytesName = nbytesName;
1587 fFileSimple.fControlBlock->fHeader.SetNbytesName(nbytesName);
1589 fFileSimple.Write(&keyRoot, keyRoot.fKeyHeaderSize, 100);
1591 fFileSimple.Write(&strTFile, strTFile.GetSize());
1592 fFileSimple.Write(&strFileName, strFileName.GetSize());
1593 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1595 fFileSimple.Write(&strFileName, strFileName.GetSize());
1596 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1598 fFileSimple.fControlBlock->fSeekFileRecord = fFileSimple.fFilePos;
1599 fFileSimple.Write(&fFileSimple.fControlBlock->fFileRecord, fFileSimple.fControlBlock->fFileRecord.GetSize());
1600 fFileSimple.Write(&uuid, uuid.GetSize());
1603 RUInt32BE padding{0};
1604 for (
int i = 0; i < 3; ++i)
1605 fFileSimple.Write(&padding,
sizeof(padding));
1606 fFileSimple.fKeyOffset = fFileSimple.fFilePos;
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#define ROOT_VERSION_CODE
#define ClassDefInlineOverride(name, id)
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Binding & operator=(OUT(*fun)(void))
void ReadBuffer(char *&buffer) override
The RKeyBlob writes an invisible key into a TFile.
void Reserve(size_t nbytes, std::uint64_t *seekKey)
Register a new key for a data record of size nbytes.
RResult< RNTuple > GetNTuple(std::string_view ntupleName)
Extracts header and footer location for the RNTuple identified by ntupleName.
RMiniFileReader()=default
RResult< RNTuple > GetNTupleProper(std::string_view ntupleName)
Used when the file turns out to be a TFile container.
RNTuple CreateAnchor(std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor, std::uint16_t versionPatch, std::uint64_t seekHeader, std::uint64_t nbytesHeader, std::uint64_t lenHeader, std::uint64_t seekFooter, std::uint64_t nbytesFooter, std::uint64_t lenFooter, std::uint64_t maxKeySize)
RResult< RNTuple > GetNTupleBare(std::string_view ntupleName)
Used when the file container turns out to be a bare file.
void ReadBuffer(void *buffer, size_t nbytes, std::uint64_t offset)
Reads a given byte range from the file into the provided memory buffer.
Helper class to compress data blocks in the ROOT compression frame format.
size_t Zip(const void *from, size_t nbytes, int compression, Writer_t fnWriter)
Returns the size of the compressed data.
Helper class to uncompress data blocks in the ROOT compression frame format.
void Unzip(const void *from, size_t nbytes, size_t dataLen, void *to)
The nbytes parameter provides the size ls of the from buffer.
Write RNTuple data blocks in a TFile or a bare file container.
std::uint64_t WriteBlob(const void *data, size_t nbytes, size_t len)
Writes a new record as an RBlob key into the file.
std::uint64_t WriteNTupleFooter(const void *data, size_t nbytes, size_t lenFooter)
Writes the compressed footer and registeres its location; lenFooter is the size of the uncompressed f...
void WriteTFileKeysList()
Write the TList with the RNTuple key.
void Commit()
Writes the RNTuple key to the file so that the header and footer keys can be found.
std::uint64_t ReserveBlob(size_t nbytes, size_t len)
Reserves a new record as an RBlob key in the file.
RFileSimple fFileSimple
For simple use cases, survives without libRIO dependency.
static std::unique_ptr< RNTupleFileWriter > Append(std::string_view ntupleName, TFile &file)
Add a new RNTuple identified by ntupleName to the existing TFile.
void WriteTFileNTupleKey()
The only key that will be visible in file->ls()
void WriteTFileFreeList()
Last record in the file.
EContainerFormat
For testing purposes, RNTuple data can be written into a bare file container instead of a ROOT file.
static std::unique_ptr< RNTupleFileWriter > Recreate(std::string_view ntupleName, std::string_view path, int defaultCompression, EContainerFormat containerFormat)
Create or truncate the local file given by path with the new empty RNTuple identified by ntupleName.
RNTupleFileWriter(std::string_view name)
void WriteTFileSkeleton(int defaultCompression)
For a TFile container written by a C file stream, write the header and TFile object.
void WriteBareFileSkeleton(int defaultCompression)
For a bare file, which is necessarily written by a C file stream, write file header.
void WriteTFileStreamerInfo()
Write the compressed streamer info record with the description of the RNTuple class.
std::uint64_t WriteNTupleHeader(const void *data, size_t nbytes, size_t lenHeader)
Writes the compressed header and registeres its location; lenHeader is the size of the uncompressed h...
void WriteIntoReservedBlob(const void *buffer, size_t nbytes, std::int64_t offset)
Write into a reserved record; the caller is responsible for making sure that the written byte range i...
Base class for all ROOT issued exceptions.
Representation of an RNTuple data set in a ROOT file.
std::uint16_t fVersionMajor
Changing the major version indicates forward incompatible changes; such changes should correspond to ...
std::uint64_t fSeekFooter
The file offset of the footer excluding the TKey part.
std::uint64_t GetLenFooter() const
std::uint64_t fMaxKeySize
The maximum size for a TKey payload. Payloads bigger than this size will be chained as multiple blobs...
std::uint64_t GetNBytesHeader() const
std::uint64_t GetLenHeader() const
std::uint16_t fVersionMinor
Changing the minor version indicates new optional fields added to the RNTuple meta-data.
std::uint16_t fVersionEpoch
Version of the RNTuple binary format that the writer supports (see specification).
std::uint16_t GetVersionEpoch() const
std::uint64_t fNBytesFooter
The size of the compressed ntuple footer.
std::uint64_t fLenFooter
The size of the uncompressed ntuple footer.
std::uint64_t GetNBytesFooter() const
std::uint64_t GetMaxKeySize() const
std::uint64_t GetSeekHeader() const
std::uint64_t fLenHeader
The size of the uncompressed ntuple header.
std::uint64_t fNBytesHeader
The size of the compressed ntuple header.
std::uint16_t GetVersionMinor() const
std::uint16_t fVersionPatch
Changing the patch version indicates new backported features from newer binary format versions.
std::uint16_t GetVersionMajor() const
std::uint16_t GetVersionPatch() const
std::uint64_t GetSeekFooter() const
std::uint64_t fSeekHeader
The file offset of the header excluding the TKey part.
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
The RRawFile provides read-only access to local and remote files.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Int_t Sizeof() const override
Return the size in bytes of the key header structure.
Int_t fVersion
Key version identifier.
Short_t fKeylen
Number of bytes for the key itself.
Long64_t fSeekKey
Location of object on file.
virtual void Create(Int_t nbytes, TFile *f=nullptr)
Create a TKey object of specified size.
TString fClassName
Object Class name.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Helper templated class for swapping bytes; specializations for N={2,4,8} are provided below.
void Write(const void *buffer, size_t nbytes, std::int64_t offset)
Low-level writing using a TFile.
std::uint64_t WriteKey(const void *buffer, size_t nbytes, size_t len)
Writes an RBlob opaque key with the provided buffer as data record and returns the offset of the reco...
std::unique_ptr< ROOT::Experimental::Internal::RTFileControlBlock > fControlBlock
Keeps track of TFile control structures, which need to be updated on committing the data set.
void Write(const void *buffer, size_t nbytes, std::int64_t offset=-1)
Writes bytes in the open stream, either at fFilePos or at the given offset.
std::uint64_t WriteKey(const void *buffer, std::size_t nbytes, std::size_t len, std::int64_t offset=-1, std::uint64_t directoryOffset=100, const std::string &className="", const std::string &objectName="", const std::string &title="")
Writes a TKey including the data record, given by buffer, into fFile; returns the file offset to the ...
If a TFile container is written by a C stream (simple file), on dataset commit, the file header and t...
std::uint64_t fSeekNTuple
std::uint64_t fSeekFileRecord