48 std::uint16_t fValBE = 0;
49 static std::uint16_t
Swap(std::uint16_t val) {
50 return (val & 0x00FF) << 8 | (val & 0xFF00) >> 8;
53 RUInt16BE() =
default;
54 explicit RUInt16BE(
const std::uint16_t val) : fValBE(
Swap(val)) {}
55 operator std::uint16_t()
const {
58 RUInt16BE&
operator =(
const std::uint16_t val) {
67 std::uint32_t fValBE = 0;
68 static std::uint32_t
Swap(std::uint32_t val) {
69 auto x = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
70 return (
x & 0x00FF00FF) << 8 | (
x & 0xFF00FF00) >> 8;
73 RUInt32BE() =
default;
74 explicit RUInt32BE(
const std::uint32_t val) : fValBE(
Swap(val)) {}
75 operator std::uint32_t()
const {
78 RUInt32BE&
operator =(
const std::uint32_t val) {
87 std::int32_t fValBE = 0;
88 static std::int32_t
Swap(std::int32_t val) {
89 auto x = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
90 return (
x & 0x00FF00FF) << 8 | (
x & 0xFF00FF00) >> 8;
94 explicit RInt32BE(
const std::int32_t val) : fValBE(
Swap(val)) {}
95 operator std::int32_t()
const {
107 std::uint64_t fValBE = 0;
108 static std::uint64_t
Swap(std::uint64_t val) {
109 auto x = (val & 0x00000000FFFFFFFF) << 32 | (val & 0xFFFFFFFF00000000) >> 32;
110 x = (
x & 0x0000FFFF0000FFFF) << 16 | (
x & 0xFFFF0000FFFF0000) >> 16;
111 return (
x & 0x00FF00FF00FF00FF) << 8 | (
x & 0xFF00FF00FF00FF00) >> 8;
114 RUInt64BE() =
default;
115 explicit RUInt64BE(
const std::uint64_t val) : fValBE(
Swap(val)) {}
116 operator std::uint64_t()
const {
119 RUInt64BE&
operator =(
const std::uint64_t val) {
125constexpr std::int32_t ChecksumRNTupleClass() {
126 const char ident[] =
"ROOT::Experimental::RNTuple"
150 for (
unsigned i = 0; i < (
sizeof(ident) - 1); i++)
151 id =
static_cast<std::int32_t
>(
static_cast<std::int64_t
>(
id) * 3 + ident[i]);
159 unsigned char fLName{0};
161 RTFString() =
default;
162 RTFString(
const std::string &str) {
166 fLName = str.length();
167 memcpy(fData, str.data(), fLName);
169 std::size_t GetSize()
const
182 auto now = std::chrono::system_clock::now();
183 auto tt = std::chrono::system_clock::to_time_t(now);
184 auto tm = *localtime(&
tt);
185 fDatetime = (tm.tm_year + 1900 - 1995) << 26 | (tm.tm_mon + 1) << 22 | tm.tm_mday << 17 |
186 tm.tm_hour << 12 | tm.tm_min << 6 | tm.tm_sec;
188 explicit RTFDatetime(RUInt32BE val) : fDatetime(val) {}
194 RUInt16BE fVersion{4};
195 RUInt32BE fObjLen{0};
196 RTFDatetime fDatetime;
197 RUInt16BE fKeyLen{0};
201 RUInt32BE fSeekKey{0};
202 RUInt32BE fSeekPdir{0};
205 RUInt64BE fSeekKey{0};
206 RUInt64BE fSeekPdir{0};
210 std::uint32_t fKeyHeaderSize{18 +
sizeof(fInfoShort)};
212 RTFKey() : fInfoShort() {}
213 RTFKey(std::uint64_t seekKey, std::uint64_t seekPdir,
214 const RTFString &clName,
const RTFString &objName,
const RTFString &titleName,
215 std::size_t szObjInMem, std::size_t szObjOnDisk = 0)
217 R__ASSERT(szObjInMem < std::numeric_limits<std::int32_t>::max());
218 R__ASSERT(szObjOnDisk < std::numeric_limits<std::int32_t>::max());
219 fObjLen = szObjInMem;
220 if ((seekKey >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) ||
221 (seekPdir >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())))
223 fKeyHeaderSize = 18 +
sizeof(fInfoLong);
224 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
225 fInfoLong.fSeekKey = seekKey;
226 fInfoLong.fSeekPdir = seekPdir;
227 fVersion = fVersion + 1000;
229 fKeyHeaderSize = 18 +
sizeof(fInfoShort);
230 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
231 fInfoShort.fSeekKey = seekKey;
232 fInfoShort.fSeekPdir = seekPdir;
234 fNbytes = fKeyLen + ((szObjOnDisk == 0) ? szObjInMem : szObjOnDisk);
239 if (fVersion >= 1000)
241 std::uint32_t seekKey = fInfoShort.fSeekKey;
242 std::uint32_t seekPdir = fInfoShort.fSeekPdir;
243 fInfoLong.fSeekKey = seekKey;
244 fInfoLong.fSeekPdir = seekPdir;
245 fKeyHeaderSize = fKeyHeaderSize +
sizeof(fInfoLong) -
sizeof(fInfoShort);
246 fKeyLen = fKeyLen +
sizeof(fInfoLong) -
sizeof(fInfoShort);
247 fNbytes = fNbytes +
sizeof(fInfoLong) -
sizeof(fInfoShort);
248 fVersion = fVersion + 1000;
251 std::uint32_t GetSize()
const {
258 std::uint32_t GetHeaderSize()
const {
259 if (fVersion >= 1000)
260 return 18 +
sizeof(fInfoLong);
261 return 18 +
sizeof(fInfoShort);
264 std::uint64_t GetSeekKey()
const {
265 if (fVersion >= 1000)
266 return fInfoLong.fSeekKey;
267 return fInfoShort.fSeekKey;
273 char fMagic[4]{
'r',
'o',
'o',
't' };
277 RUInt32BE fBEGIN{100};
281 RUInt32BE fSeekFree{0};
282 RUInt32BE fNbytesFree{0};
284 RUInt32BE fNbytesName{0};
285 unsigned char fUnits{4};
286 RUInt32BE fCompress{0};
287 RUInt32BE fSeekInfo{0};
288 RUInt32BE fNbytesInfo{0};
292 RUInt64BE fSeekFree{0};
293 RUInt32BE fNbytesFree{0};
295 RUInt32BE fNbytesName{0};
296 unsigned char fUnits{8};
297 RUInt32BE fCompress{0};
298 RUInt64BE fSeekInfo{0};
299 RUInt32BE fNbytesInfo{0};
303 RTFHeader() : fInfoShort() {}
304 RTFHeader(
int compression) : fInfoShort() {
305 fInfoShort.fCompress = compression;
309 if (fVersion >= 1000000)
312 std::uint32_t
end = fInfoShort.fEND;
313 std::uint32_t seekFree = fInfoShort.fSeekFree;
314 std::uint32_t nbytesFree = fInfoShort.fNbytesFree;
315 std::uint32_t nFree = fInfoShort.fNfree;
316 std::uint32_t nbytesName = fInfoShort.fNbytesName;
317 std::uint32_t compress = fInfoShort.fCompress;
318 std::uint32_t seekInfo = fInfoShort.fSeekInfo;
319 std::uint32_t nbytesInfo = fInfoShort.fNbytesInfo;
320 fInfoLong.fEND =
end;
321 fInfoLong.fSeekFree = seekFree;
322 fInfoLong.fNbytesFree = nbytesFree;
323 fInfoLong.fNfree = nFree;
324 fInfoLong.fNbytesName = nbytesName;
325 fInfoLong.fUnits = 8;
326 fInfoLong.fCompress = compress;
327 fInfoLong.fSeekInfo = seekInfo;
328 fInfoLong.fNbytesInfo = nbytesInfo;
329 fVersion = fVersion + 1000000;
332 bool IsBigFile(std::uint64_t
offset = 0)
const {
333 return (fVersion >= 1000000) || (
offset >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max()));
336 std::uint32_t GetSize()
const {
337 std::uint32_t sizeHead = 4 +
sizeof(fVersion) +
sizeof(fBEGIN);
338 if (IsBigFile())
return sizeHead +
sizeof(fInfoLong);
339 return sizeHead +
sizeof(fInfoShort);
342 std::uint64_t GetEnd()
const {
343 if (IsBigFile())
return fInfoLong.fEND;
344 return fInfoShort.fEND;
347 void SetEnd(std::uint64_t
value) {
348 if (IsBigFile(
value)) {
350 fInfoLong.fEND =
value;
352 fInfoShort.fEND =
value;
356 std::uint64_t GetSeekFree()
const {
357 if (IsBigFile())
return fInfoLong.fSeekFree;
358 return fInfoShort.fSeekFree;
361 void SetSeekFree(std::uint64_t
value) {
362 if (IsBigFile(
value)) {
364 fInfoLong.fSeekFree =
value;
366 fInfoShort.fSeekFree =
value;
370 void SetNbytesFree(std::uint32_t
value) {
372 fInfoLong.fNbytesFree =
value;
374 fInfoShort.fNbytesFree =
value;
378 void SetNbytesName(std::uint32_t
value) {
380 fInfoLong.fNbytesName =
value;
382 fInfoShort.fNbytesName =
value;
386 std::uint64_t GetSeekInfo()
const {
387 if (IsBigFile())
return fInfoLong.fSeekInfo;
388 return fInfoShort.fSeekInfo;
391 void SetSeekInfo(std::uint64_t
value) {
392 if (IsBigFile(
value)) {
394 fInfoLong.fSeekInfo =
value;
396 fInfoShort.fSeekInfo =
value;
400 void SetNbytesInfo(std::uint32_t
value) {
402 fInfoLong.fNbytesInfo =
value;
404 fInfoShort.fNbytesInfo =
value;
408 void SetCompression(std::uint32_t
value) {
410 fInfoLong.fCompress =
value;
412 fInfoShort.fCompress =
value;
420 RUInt16BE fVersion{1};
432 RTFFreeEntry() : fInfoShort() {}
433 void Set(std::uint64_t first, std::uint64_t last) {
434 if (last >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) {
435 fVersion = fVersion + 1000;
436 fInfoLong.fFirst = first;
437 fInfoLong.fLast = last;
439 fInfoShort.fFirst = first;
440 fInfoShort.fLast = last;
443 std::uint32_t GetSize() {
return (fVersion >= 1000) ? 18 : 10; }
448 RUInt16BE fVersion{1};
449 RUInt32BE fUniqueID{0};
451 explicit RTFObject(std::uint32_t bits) : fBits(bits) {}
455struct RTFStreamerElementVersionEpoch {
456 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionEpoch) -
sizeof(RUInt32BE))};
457 RUInt16BE fVersion{4};
459 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
460 RUInt16BE fVersionNamed{1};
461 RTFObject fObjectNamed{0x02000000 | 0x01000000};
463 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'E',
'p',
'o',
'c',
'h'};
468 RUInt32BE fArrLength{0};
469 RUInt32BE fArrDim{0};
470 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
471 char fLTypeName = 14;
472 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
476struct RTFStreamerElementVersionMajor {
477 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionMajor) -
sizeof(RUInt32BE))};
478 RUInt16BE fVersion{4};
480 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
481 RUInt16BE fVersionNamed{1};
482 RTFObject fObjectNamed{0x02000000 | 0x01000000};
484 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'M',
'a',
'j',
'o',
'r'};
489 RUInt32BE fArrLength{0};
490 RUInt32BE fArrDim{0};
491 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
492 char fLTypeName = 14;
493 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
497struct RTFStreamerElementVersionMinor {
498 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionMinor) -
sizeof(RUInt32BE))};
499 RUInt16BE fVersion{4};
501 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
502 RUInt16BE fVersionNamed{1};
503 RTFObject fObjectNamed{0x02000000 | 0x01000000};
505 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'M',
'i',
'n',
'o',
'r'};
510 RUInt32BE fArrLength{0};
511 RUInt32BE fArrDim{0};
512 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
513 char fLTypeName = 14;
514 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
518struct RTFStreamerElementVersionPatch {
519 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersionPatch) -
sizeof(RUInt32BE))};
520 RUInt16BE fVersion{4};
522 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
523 RUInt16BE fVersionNamed{1};
524 RTFObject fObjectNamed{0x02000000 | 0x01000000};
526 char fName[13]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n',
'P',
'a',
't',
'c',
'h'};
531 RUInt32BE fArrLength{0};
532 RUInt32BE fArrDim{0};
533 char fMaxIndex[20]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
534 char fLTypeName = 14;
535 char fTypeName[14]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
's',
'h',
'o',
'r',
't'};
539struct RTFStreamerElementSeekHeader {
540 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekHeader) -
sizeof(RUInt32BE))};
541 RUInt16BE fVersion{4};
543 RUInt32BE fByteCountNamed{0x40000000 |
544 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
545 RUInt16BE fVersionNamed{1};
546 RTFObject fObjectNamed{0x02000000 | 0x01000000};
548 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'H',
'e',
'a',
'd',
'e',
'r' };
553 RUInt32BE fArrLength{0};
554 RUInt32BE fArrDim{0};
555 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
556 char fLTypeName = 13;
557 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
561struct RTFStreamerElementNBytesHeader {
562 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesHeader) -
sizeof(RUInt32BE))};
563 RUInt16BE fVersion{4};
565 RUInt32BE fByteCountNamed{0x40000000 |
566 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
567 RUInt16BE fVersionNamed{1};
568 RTFObject fObjectNamed{0x02000000 | 0x01000000};
570 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'H',
'e',
'a',
'd',
'e',
'r' };
575 RUInt32BE fArrLength{0};
576 RUInt32BE fArrDim{0};
577 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
578 char fLTypeName = 13;
579 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
583struct RTFStreamerElementLenHeader {
584 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenHeader) -
sizeof(RUInt32BE))};
585 RUInt16BE fVersion{4};
587 RUInt32BE fByteCountNamed{0x40000000 |
588 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
589 RUInt16BE fVersionNamed{1};
590 RTFObject fObjectNamed{0x02000000 | 0x01000000};
592 char fName[10]{
'f',
'L',
'e',
'n',
'H',
'e',
'a',
'd',
'e',
'r' };
597 RUInt32BE fArrLength{0};
598 RUInt32BE fArrDim{0};
599 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
600 char fLTypeName = 13;
601 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
605struct RTFStreamerElementSeekFooter {
606 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekFooter) -
sizeof(RUInt32BE))};
607 RUInt16BE fVersion{4};
609 RUInt32BE fByteCountNamed{0x40000000 |
610 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
611 RUInt16BE fVersionNamed{1};
612 RTFObject fObjectNamed{0x02000000 | 0x01000000};
614 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'F',
'o',
'o',
't',
'e',
'r' };
619 RUInt32BE fArrLength{0};
620 RUInt32BE fArrDim{0};
621 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
622 char fLTypeName = 13;
623 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
627struct RTFStreamerElementNBytesFooter {
628 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesFooter) -
sizeof(RUInt32BE))};
629 RUInt16BE fVersion{4};
631 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
632 RUInt16BE fVersionNamed{1};
633 RTFObject fObjectNamed{0x02000000 | 0x01000000};
635 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'F',
'o',
'o',
't',
'e',
'r' };
640 RUInt32BE fArrLength{0};
641 RUInt32BE fArrDim{0};
642 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
643 char fLTypeName = 13;
644 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
648struct RTFStreamerElementLenFooter {
649 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenFooter) -
sizeof(RUInt32BE))};
650 RUInt16BE fVersion{4};
652 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
653 RUInt16BE fVersionNamed{1};
654 RTFObject fObjectNamed{0x02000000 | 0x01000000};
656 char fName[10]{
'f',
'L',
'e',
'n',
'F',
'o',
'o',
't',
'e',
'r' };
661 RUInt32BE fArrLength{0};
662 RUInt32BE fArrDim{0};
663 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
664 char fLTypeName = 13;
665 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g'};
669struct RTFStreamerElementChecksum {
670 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementChecksum) -
sizeof(RUInt32BE))};
671 RUInt16BE fVersion{4};
673 RUInt32BE fByteCountNamed{0x40000000 |
674 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 11)};
675 RUInt16BE fVersionNamed{1};
676 RTFObject fObjectNamed{0x02000000 | 0x01000000};
678 char fName[9]{
'f',
'C',
'h',
'e',
'c',
'k',
's',
'u',
'm'};
683 RUInt32BE fArrLength{0};
684 RUInt32BE fArrDim{0};
685 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
686 char fLTypeName = 13;
687 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
691struct RTFStreamerVersionEpoch {
692 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionEpoch) -
sizeof(RUInt32BE))};
693 RUInt32BE fNewClassTag{0xffffffff};
694 char fClassName[19]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'B',
'a',
's',
'i',
'c',
'T',
'y',
'p',
'e',
'\0'};
695 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionEpoch) - 2 *
sizeof(RUInt32BE) -
696 19 -
sizeof(RUInt32BE))};
697 RUInt16BE fVersion{2};
698 RTFStreamerElementVersionEpoch fStreamerElementVersionEpoch;
702struct RTFStreamerVersionMajor {
703 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionMajor) -
sizeof(RUInt32BE))};
704 RUInt32BE fClassTag{0x80000000};
705 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionMajor) - 3 *
sizeof(RUInt32BE))};
706 RUInt16BE fVersion{2};
707 RTFStreamerElementVersionMajor fStreamerElementVersionMajor;
711struct RTFStreamerVersionMinor {
712 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionMinor) -
sizeof(RUInt32BE))};
713 RUInt32BE fClassTag{0x80000000};
714 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionMinor) - 3 *
sizeof(RUInt32BE))};
715 RUInt16BE fVersion{2};
716 RTFStreamerElementVersionMinor fStreamerElementVersionMinor;
720struct RTFStreamerVersionPatch {
721 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersionPatch) -
sizeof(RUInt32BE))};
722 RUInt32BE fClassTag{0x80000000};
723 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerVersionPatch) - 3 *
sizeof(RUInt32BE))};
724 RUInt16BE fVersion{2};
725 RTFStreamerElementVersionPatch fStreamerElementVersionPatch;
729struct RTFStreamerSeekHeader {
730 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekHeader) -
sizeof(RUInt32BE))};
731 RUInt32BE fClassTag{0x80000000};
732 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekHeader) - 3 *
sizeof(RUInt32BE))};
733 RUInt16BE fVersion{2};
734 RTFStreamerElementSeekHeader fStreamerElementSeekHeader;
738struct RTFStreamerNBytesHeader {
739 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) -
sizeof(RUInt32BE))};
740 RUInt32BE fClassTag{0x80000000};
741 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) - 3 *
sizeof(RUInt32BE))};
742 RUInt16BE fVersion{2};
743 RTFStreamerElementNBytesHeader fStreamerElementNBytesHeader;
747struct RTFStreamerLenHeader {
748 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenHeader) -
sizeof(RUInt32BE))};
749 RUInt32BE fClassTag{0x80000000};
750 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenHeader) - 3 *
sizeof(RUInt32BE))};
751 RUInt16BE fVersion{2};
752 RTFStreamerElementLenHeader fStreamerElementLenHeader;
756struct RTFStreamerSeekFooter {
757 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekFooter) -
sizeof(RUInt32BE))};
758 RUInt32BE fClassTag{0x80000000};
759 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekFooter) - 3 *
sizeof(RUInt32BE))};
760 RUInt16BE fVersion{2};
761 RTFStreamerElementSeekFooter fStreamerElementSeekFooter;
765struct RTFStreamerNBytesFooter {
766 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) -
sizeof(RUInt32BE))};
767 RUInt32BE fClassTag{0x80000000};
768 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) - 3 *
sizeof(RUInt32BE))};
769 RUInt16BE fVersion{2};
770 RTFStreamerElementNBytesFooter fStreamerElementNBytesFooter;
774struct RTFStreamerLenFooter {
775 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenFooter) -
sizeof(RUInt32BE))};
776 RUInt32BE fClassTag{0x80000000};
777 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenFooter) - 3 *
sizeof(RUInt32BE))};
778 RUInt16BE fVersion{2};
779 RTFStreamerElementLenFooter fStreamerElementLenFooter;
783struct RTFStreamerChecksum {
784 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerChecksum) -
sizeof(RUInt32BE))};
785 RUInt32BE fClassTag{0x80000000};
786 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerChecksum) - 3 *
sizeof(RUInt32BE))};
787 RUInt16BE fVersion{2};
788 RTFStreamerElementChecksum fStreamerElementChecksum;
792struct RTFStreamerInfoObject {
793 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoObject) -
sizeof(fByteCount))};
794 RUInt32BE fNewClassTag{0xffffffff};
795 char fClassName[14]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'I',
'n',
'f',
'o',
'\0' };
796 RUInt32BE fByteCountRemaining{0x40000000 |
797 (
sizeof(RTFStreamerInfoObject) - 2 *
sizeof(RUInt32BE) - 14 -
sizeof(RUInt32BE))};
798 RUInt16BE fVersion{9};
800 RUInt32BE fByteCountNamed{0x40000000 |
801 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 29 )};
802 RUInt16BE fVersionNamed{1};
803 RTFObject fObjectNamed{0x02000000 | 0x01000000 | 0x00010000};
805 char fName[27]{
'R',
'O',
'O',
'T',
':',
':',
806 'E',
'x',
'p',
'e',
'r',
'i',
'm',
'e',
'n',
't',
'a',
'l',
':',
':',
807 'R',
'N',
'T',
'u',
'p',
'l',
'e'};
810 RInt32BE fChecksum{ChecksumRNTupleClass()};
811 RUInt32BE fVersionRNTuple{4};
813 RUInt32BE fByteCountObjArr{0x40000000 |
814 (
sizeof(RUInt32BE) + 10 +
sizeof(RUInt32BE) +
815 sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2*
sizeof(RUInt32BE) +
816 sizeof(fStreamers))};
817 RUInt32BE fNewClassTagObjArray{0xffffffff};
818 char fClassNameObjArray[10]{
'T',
'O',
'b',
'j',
'A',
'r',
'r',
'a',
'y',
'\0'};
819 RUInt32BE fByteCountObjArrRemaining{0x40000000 |
820 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2*
sizeof(RUInt32BE) +
821 sizeof(fStreamers))};
822 RUInt16BE fVersionObjArr{3};
823 RTFObject fObjectObjArr{0x02000000};
826 RUInt32BE fNObjects{11};
827 RUInt32BE fLowerBound{0};
830 RTFStreamerVersionEpoch fStreamerVersionEpoch;
831 RTFStreamerVersionMajor fStreamerVersionMajor;
832 RTFStreamerVersionMinor fStreamerVersionMinor;
833 RTFStreamerVersionPatch fStreamerVersionPatch;
834 RTFStreamerSeekHeader fStreamerSeekHeader;
835 RTFStreamerNBytesHeader fStreamerNBytesHeader;
836 RTFStreamerLenHeader fStreamerLenHeader;
837 RTFStreamerSeekFooter fStreamerSeekFooter;
838 RTFStreamerNBytesFooter fStreamerNBytesFooter;
839 RTFStreamerLenFooter fStreamerLenFooter;
840 RTFStreamerChecksum fStreamerChecksum;
845struct RTFStreamerInfoList {
846 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoList) -
sizeof(fByteCount))};
847 RUInt16BE fVersion{5};
848 RTFObject fObject{0x02000000};
850 RUInt32BE fNObjects{1};
851 RTFStreamerInfoObject fStreamerInfo;
854 std::uint32_t GetSize()
const {
return sizeof(RTFStreamerInfoList); }
860 std::uint32_t GetSize()
const {
return sizeof(RTFKeyList); }
861 explicit RTFKeyList(std::uint32_t nKeys) : fNKeys(nKeys) {}
866 RUInt16BE fClassVersion{5};
869 RUInt32BE fNBytesKeys{0};
870 RUInt32BE fNBytesName{0};
874 RUInt32BE fSeekDir{100};
875 RUInt32BE fSeekParent{0};
876 RUInt32BE fSeekKeys{0};
879 RUInt64BE fSeekDir{100};
880 RUInt64BE fSeekParent{0};
881 RUInt64BE fSeekKeys{0};
885 RTFFile() : fInfoShort() {}
888 std::uint32_t GetSize()
const
890 if (fClassVersion >= 1000)
891 return sizeof(RTFFile);
892 return 18 +
sizeof(fInfoShort);
895 std::uint64_t GetSeekKeys()
const
897 if (fClassVersion >= 1000)
898 return fInfoLong.fSeekKeys;
899 return fInfoShort.fSeekKeys;
902 void SetSeekKeys(std::uint64_t seekKeys)
904 if (seekKeys >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) {
905 std::uint32_t seekDir = fInfoShort.fSeekDir;
906 std::uint32_t seekParent = fInfoShort.fSeekParent;
907 fInfoLong.fSeekDir = seekDir;
908 fInfoLong.fSeekParent = seekParent;
909 fInfoLong.fSeekKeys = seekKeys;
910 fClassVersion = fClassVersion + 1000;
912 fInfoShort.fSeekKeys = seekKeys;
919 RUInt16BE fVersionClass{1};
920 unsigned char fUUID[16] = {0};
923 std::uint32_t GetSize()
const {
return sizeof(RTFUUID); }
928 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFNTuple) -
sizeof(fByteCount))};
929 RUInt16BE fVersionClass{4};
930 RUInt16BE fVersionEpoch{0};
931 RUInt16BE fVersionMajor{0};
932 RUInt16BE fVersionMinor{0};
933 RUInt16BE fVersionPatch{0};
934 RUInt64BE fSeekHeader{0};
935 RUInt64BE fNBytesHeader{0};
936 RUInt64BE fLenHeader{0};
937 RUInt64BE fSeekFooter{0};
938 RUInt64BE fNBytesFooter{0};
939 RUInt64BE fLenFooter{0};
940 RUInt64BE fChecksum{0};
942 RTFNTuple() =
default;
955 fChecksum = XXH3_64bits(GetPtrCkData(), GetSizeCkData());
957 std::uint32_t GetSize()
const {
return sizeof(RTFNTuple); }
959 std::uint32_t GetOffsetCkData() {
return sizeof(fByteCount) +
sizeof(fVersionClass); }
960 std::uint32_t GetSizeCkData() {
return GetSize() - GetOffsetCkData() -
sizeof(fChecksum); }
961 unsigned char *GetPtrCkData() {
return reinterpret_cast<unsigned char *
>(
this) + GetOffsetCkData(); }
965struct RBareFileHeader {
966 char fMagic[7]{
'r',
'n',
't',
'u',
'p',
'l',
'e' };
970 RUInt32BE fFormatVersion{1};
971 RUInt32BE fCompress{0};
978constexpr char const *kBlobClassName =
"RBlob";
980constexpr char const *kNTupleClassName =
"ROOT::Experimental::RNTuple";
984class RKeyBlob :
public TKey {
986 explicit RKeyBlob(
TFile *file) :
TKey(file) {
987 fClassName = kBlobClassName;
993 void Reserve(
size_t nbytes, std::uint64_t *seekKey)
1004namespace Experimental {
1025 std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor, std::uint16_t versionPatch,
1026 std::uint64_t seekHeader, std::uint64_t nbytesHeader, std::uint64_t lenHeader, std::uint64_t seekFooter,
1027 std::uint64_t nbytesFooter, std::uint64_t lenFooter, std::uint64_t checksum)
1049 if (std::string(ident, 4) ==
"root")
1050 return GetNTupleProper(ntupleName);
1052 return GetNTupleBare(ntupleName);
1058 RTFHeader fileHeader;
1059 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
1063 ReadBuffer(&key,
sizeof(key), fileHeader.fBEGIN);
1065 std::uint64_t
offset = fileHeader.fBEGIN + key.fKeyLen;
1075 offset = file.GetSeekKeys();
1081 for (
unsigned int i = 0; i < nKeys; ++i) {
1083 auto offsetNextKey =
offset + key.fKeyLen;
1085 offset += key.GetHeaderSize();
1088 if (std::string_view(
name.fData,
name.fLName) != kNTupleClassName) {
1095 if (std::string_view(
name.fData,
name.fLName) == ntupleName) {
1102 return R__FAIL(
"no RNTuple named '" + std::string(ntupleName)
1103 +
"' in file '" + fRawFile->GetUrl() +
"'");
1106 ReadBuffer(&key,
sizeof(key), key.GetSeekKey());
1107 offset = key.GetSeekKey() + key.fKeyLen;
1109 if (key.fObjLen <
sizeof(RTFNTuple)) {
1110 return R__FAIL(
"invalid anchor size: " + std::to_string(key.fObjLen) +
" < " + std::to_string(
sizeof(RTFNTuple)));
1113 auto bufAnchor = std::make_unique<unsigned char[]>(key.fObjLen);
1114 RTFNTuple *ntuple =
new (bufAnchor.get()) RTFNTuple;
1116 auto objNbytes = key.GetSize() - key.fKeyLen;
1118 if (objNbytes != key.fObjLen) {
1120 decompressor.
Unzip(bufAnchor.get(), objNbytes, key.fObjLen);
1123 if (ntuple->fVersionClass < 4) {
1124 return R__FAIL(
"invalid anchor, unsupported pre-release of RNTuple");
1129 RUInt64BE *ckOnDisk =
reinterpret_cast<RUInt64BE *
>(bufAnchor.get() + key.fObjLen -
sizeof(RUInt64BE));
1130 auto lenCkData = ntuple->GetSizeCkData() + key.fObjLen -
sizeof(RTFNTuple);
1131 auto ckCalc = XXH3_64bits(ntuple->GetPtrCkData(), lenCkData);
1132 if (ckCalc != (uint64_t)(*ckOnDisk)) {
1133 return R__FAIL(
"RNTuple anchor checksum mismatch");
1136 return CreateAnchor(ntuple->fVersionEpoch, ntuple->fVersionMajor, ntuple->fVersionMinor, ntuple->fVersionPatch,
1137 ntuple->fSeekHeader, ntuple->fNBytesHeader, ntuple->fLenHeader, ntuple->fSeekFooter,
1138 ntuple->fNBytesFooter, ntuple->fLenFooter, ntuple->fChecksum);
1144 RBareFileHeader fileHeader;
1145 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
1147 auto offset =
sizeof(fileHeader);
1150 std::string_view foundName(
name.fData,
name.fLName);
1151 if (foundName != ntupleName) {
1152 return R__FAIL(
"expected RNTuple named '" + std::string(ntupleName)
1153 +
"' but instead found '" + std::string(foundName)
1154 +
"' in file '" + fRawFile->GetUrl() +
"'");
1160 auto checksum = XXH3_64bits(ntuple.GetPtrCkData(), ntuple.GetSizeCkData());
1161 if (checksum !=
static_cast<uint64_t
>(ntuple.fChecksum))
1162 return R__FAIL(
"RNTuple bare file: anchor checksum mismatch");
1163 return CreateAnchor(ntuple.fVersionEpoch, ntuple.fVersionMajor, ntuple.fVersionMinor, ntuple.fVersionPatch,
1164 ntuple.fSeekHeader, ntuple.fNBytesHeader, ntuple.fLenHeader, ntuple.fSeekFooter,
1165 ntuple.fNBytesFooter, ntuple.fLenFooter, ntuple.fChecksum);
1171 auto nread = fRawFile->ReadAt(buffer, nbytes,
offset);
1187 const void *buffer,
size_t nbytes, std::int64_t
offset)
1191 if ((
offset >= 0) && (
static_cast<std::uint64_t
>(
offset) != fFilePos)) {
1193 retval = fseeko64(fFile,
offset, SEEK_SET);
1195 retval = fseek(fFile,
offset, SEEK_SET);
1201 retval = fwrite(buffer, 1, nbytes, fFile);
1202 if (retval != nbytes)
1209 const void *buffer, std::size_t nbytes, std::size_t
len, std::int64_t
offset,
1210 std::uint64_t directoryOffset,
1211 const std::string &className,
1212 const std::string &objectName,
1213 const std::string &title)
1217 RTFString strClass{className};
1218 RTFString strObject{objectName};
1219 RTFString strTitle{title};
1221 RTFKey key(fKeyOffset, directoryOffset, strClass, strObject, strTitle,
len, nbytes);
1222 Write(&key, key.fKeyHeaderSize, fKeyOffset);
1223 Write(&strClass, strClass.GetSize());
1224 Write(&strObject, strObject.GetSize());
1225 Write(&strTitle, strTitle.GetSize());
1226 auto offsetData = fFilePos;
1228 fKeyOffset = offsetData + nbytes;
1230 Write(buffer, nbytes);
1240 const void *buffer,
size_t nbytes, std::int64_t
offset)
1244 bool rv = fFile->WriteBuffer((
char *)(buffer), nbytes);
1251 const void *buffer,
size_t nbytes,
size_t len)
1253 std::uint64_t offsetKey;
1254 RKeyBlob keyBlob(fFile);
1257 keyBlob.Reserve(nbytes, &offsetKey);
1260 RTFString strClass{kBlobClassName};
1261 RTFString strObject;
1263 RTFKey keyHeader(
offset,
offset, strClass, strObject, strTitle,
len, nbytes);
1265 keyHeader.MakeBigKey();
1267 Write(&keyHeader, keyHeader.fKeyHeaderSize,
offset);
1268 offset += keyHeader.fKeyHeaderSize;
1269 Write(&strClass, strClass.GetSize(),
offset);
1270 offset += strClass.GetSize();
1271 Write(&strObject, strObject.GetSize(),
offset);
1272 offset += strObject.GetSize();
1273 Write(&strTitle, strTitle.GetSize(),
offset);
1274 offset += strTitle.GetSize();
1275 auto offsetData =
offset;
1277 Write(buffer, nbytes,
offset);
1301 std::string fileName(path);
1302 size_t idxDirSep = fileName.find_last_of(
"\\/");
1303 if (idxDirSep != std::string::npos) {
1304 fileName.erase(0, idxDirSep + 1);
1307 FILE *fileStream = fopen64(std::string(path.data(), path.size()).c_str(),
"wb");
1309 FILE *fileStream = fopen(std::string(path.data(), path.size()).c_str(),
"wb");
1314 writer->fFileSimple.fFile = fileStream;
1315 writer->fFileName = fileName;
1317 switch (containerFormat) {
1318 case EContainerFormat::kTFile:
writer->WriteTFileSkeleton(defaultCompression);
break;
1319 case EContainerFormat::kBare:
1321 writer->WriteBareFileSkeleton(defaultCompression);
1324 R__ASSERT(
false &&
"Internal error: unhandled container format");
1332 std::string_view ntupleName,
TFile &file)
1335 writer->fFileProper.fFile = &file;
1344 fFileProper.fFile->WriteObject(&fNTupleAnchor, fNTupleName.c_str());
1345 fFileProper.fFile->Write();
1353 RTFNTuple ntupleOnDisk(fNTupleAnchor);
1354 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize(), fFileSimple.fControlBlock->fSeekNTuple);
1355 fflush(fFileSimple.fFile);
1359 WriteTFileNTupleKey();
1360 WriteTFileKeysList();
1361 WriteTFileStreamerInfo();
1362 WriteTFileFreeList();
1365 fFileSimple.Write(&fFileSimple.fControlBlock->fHeader, fFileSimple.fControlBlock->fHeader.GetSize(), 0);
1366 fFileSimple.Write(&fFileSimple.fControlBlock->fFileRecord, fFileSimple.fControlBlock->fFileRecord.GetSize(),
1367 fFileSimple.fControlBlock->fSeekFileRecord);
1368 fflush(fFileSimple.fFile);
1377 offset = fFileSimple.fKeyOffset;
1378 fFileSimple.Write(
data, nbytes);
1379 fFileSimple.fKeyOffset += nbytes;
1381 offset = fFileSimple.WriteKey(
data, nbytes,
len, -1, 100, kBlobClassName);
1394 offset = fFileSimple.fKeyOffset;
1395 fFileSimple.fKeyOffset += nbytes;
1397 offset = fFileSimple.WriteKey(
nullptr, nbytes,
len, -1, 100, kBlobClassName);
1400 offset = fFileProper.WriteKey(
nullptr, nbytes,
len);
1409 fFileSimple.Write(buffer, nbytes,
offset);
1411 fFileProper.Write(buffer, nbytes,
offset);
1416 const void *
data,
size_t nbytes,
size_t lenHeader)
1418 auto offset = WriteBlob(
data, nbytes, lenHeader);
1419 fNTupleAnchor.fLenHeader = lenHeader;
1420 fNTupleAnchor.fNBytesHeader = nbytes;
1421 fNTupleAnchor.fSeekHeader =
offset;
1427 const void *
data,
size_t nbytes,
size_t lenFooter)
1429 auto offset = WriteBlob(
data, nbytes, lenFooter);
1430 fNTupleAnchor.fLenFooter = lenFooter;
1431 fNTupleAnchor.fNBytesFooter = nbytes;
1432 fNTupleAnchor.fSeekFooter =
offset;
1439 RBareFileHeader bareHeader;
1440 bareHeader.fCompress = defaultCompression;
1441 fFileSimple.Write(&bareHeader,
sizeof(bareHeader), 0);
1442 RTFString ntupleName{fNTupleName};
1443 fFileSimple.Write(&ntupleName, ntupleName.GetSize());
1446 RTFNTuple ntupleOnDisk;
1447 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fFilePos;
1448 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize());
1449 fFileSimple.fKeyOffset = fFileSimple.fFilePos;
1454 RTFString strTList{
"TList"};
1455 RTFString strStreamerInfo{
"StreamerInfo"};
1456 RTFString strStreamerTitle{
"Doubly linked list"};
1458 fFileSimple.fControlBlock->fHeader.SetSeekInfo(fFileSimple.fKeyOffset);
1459 RTFKey keyStreamerInfo(
1460 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100, strTList, strStreamerInfo, strStreamerTitle, 0);
1461 RTFStreamerInfoList streamerInfo;
1462 auto classTagOffset = keyStreamerInfo.fKeyLen + offsetof(
struct RTFStreamerInfoList, fStreamerInfo) +
1463 offsetof(
struct RTFStreamerInfoObject, fStreamers) +
1464 offsetof(
struct RTFStreamerVersionEpoch, fNewClassTag) + 2;
1465 streamerInfo.fStreamerInfo.fStreamers.fStreamerVersionMajor.fClassTag = 0x80000000 | classTagOffset;
1466 streamerInfo.fStreamerInfo.fStreamers.fStreamerVersionMinor.fClassTag = 0x80000000 | classTagOffset;
1467 streamerInfo.fStreamerInfo.fStreamers.fStreamerVersionPatch.fClassTag = 0x80000000 | classTagOffset;
1468 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekHeader.fClassTag = 0x80000000 | classTagOffset;
1469 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesHeader.fClassTag = 0x80000000 | classTagOffset;
1470 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenHeader.fClassTag = 0x80000000 | classTagOffset;
1471 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekFooter.fClassTag = 0x80000000 | classTagOffset;
1472 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesFooter.fClassTag = 0x80000000 | classTagOffset;
1473 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenFooter.fClassTag = 0x80000000 | classTagOffset;
1474 streamerInfo.fStreamerInfo.fStreamers.fStreamerChecksum.fClassTag = 0x80000000 | classTagOffset;
1476 auto szStreamerInfo = compressor.
Zip(&streamerInfo, streamerInfo.GetSize(), 1);
1477 fFileSimple.WriteKey(compressor.
GetZipBuffer(), szStreamerInfo, streamerInfo.GetSize(),
1478 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100,
1479 "TList",
"StreamerInfo",
"Doubly linked list");
1480 fFileSimple.fControlBlock->fHeader.SetNbytesInfo(
1481 fFileSimple.fFilePos - fFileSimple.fControlBlock->fHeader.GetSeekInfo());
1487 RTFString strRNTupleClass{
"ROOT::Experimental::RNTuple"};
1488 RTFString strRNTupleName{fNTupleName};
1489 RTFString strFileName{fFileName};
1491 RTFKey keyRNTuple(fFileSimple.fControlBlock->fSeekNTuple, 100, strRNTupleClass, strRNTupleName, strEmpty,
1492 RTFNTuple().GetSize());
1494 fFileSimple.fControlBlock->fFileRecord.SetSeekKeys(fFileSimple.fKeyOffset);
1495 RTFKeyList keyList{1};
1496 RTFKey keyKeyList(fFileSimple.fControlBlock->fFileRecord.GetSeekKeys(), 100, strEmpty, strFileName, strEmpty,
1497 keyList.GetSize() + keyRNTuple.fKeyLen);
1498 fFileSimple.Write(&keyKeyList, keyKeyList.fKeyHeaderSize, fFileSimple.fControlBlock->fFileRecord.GetSeekKeys());
1499 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1500 fFileSimple.Write(&strFileName, strFileName.GetSize());
1501 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1502 fFileSimple.Write(&keyList, keyList.GetSize());
1503 fFileSimple.Write(&keyRNTuple, keyRNTuple.fKeyHeaderSize);
1505 fFileSimple.Write(&strRNTupleClass, strRNTupleClass.GetSize());
1506 fFileSimple.Write(&strRNTupleName, strRNTupleName.GetSize());
1507 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1508 fFileSimple.fControlBlock->fFileRecord.fNBytesKeys =
1509 fFileSimple.fFilePos - fFileSimple.fControlBlock->fFileRecord.GetSeekKeys();
1510 fFileSimple.fKeyOffset = fFileSimple.fFilePos;
1515 fFileSimple.fControlBlock->fHeader.SetSeekFree(fFileSimple.fKeyOffset);
1517 RTFString strFileName{fFileName};
1518 RTFFreeEntry freeEntry;
1519 RTFKey keyFreeList(fFileSimple.fControlBlock->fHeader.GetSeekFree(), 100, strEmpty, strFileName, strEmpty,
1520 freeEntry.GetSize());
1521 std::uint64_t firstFree = fFileSimple.fControlBlock->fHeader.GetSeekFree() + keyFreeList.GetSize();
1522 freeEntry.Set(firstFree, std::max(2000000000ULL, ((firstFree / 1000000000ULL) + 1) * 1000000000ULL));
1523 fFileSimple.WriteKey(&freeEntry, freeEntry.GetSize(), freeEntry.GetSize(),
1524 fFileSimple.fControlBlock->fHeader.GetSeekFree(), 100,
"", fFileName,
"");
1525 fFileSimple.fControlBlock->fHeader.SetNbytesFree(fFileSimple.fFilePos -
1526 fFileSimple.fControlBlock->fHeader.GetSeekFree());
1527 fFileSimple.fControlBlock->fHeader.SetEnd(fFileSimple.fFilePos);
1532 RTFString strRNTupleClass{
"ROOT::Experimental::RNTuple"};
1533 RTFString strRNTupleName{fNTupleName};
1536 RTFNTuple ntupleOnDisk(fNTupleAnchor);
1537 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fKeyOffset;
1538 fFileSimple.WriteKey(&ntupleOnDisk, ntupleOnDisk.GetSize(), ntupleOnDisk.GetSize(),
1539 fFileSimple.fControlBlock->fSeekNTuple, 100,
"ROOT::Experimental::RNTuple", fNTupleName,
"");
1544 RTFString strTFile{
"TFile"};
1545 RTFString strFileName{fFileName};
1548 fFileSimple.fControlBlock->fHeader = RTFHeader(defaultCompression);
1553 RTFKey keyRoot(100, 0, strTFile, strFileName, strEmpty,
1554 sizeof(RTFFile) + strFileName.GetSize() + strEmpty.GetSize() + uuid.GetSize());
1555 std::uint32_t nbytesName = keyRoot.fKeyLen + strFileName.GetSize() + 1;
1556 fFileSimple.fControlBlock->fFileRecord.fNBytesName = nbytesName;
1557 fFileSimple.fControlBlock->fHeader.SetNbytesName(nbytesName);
1559 fFileSimple.Write(&keyRoot, keyRoot.fKeyHeaderSize, 100);
1561 fFileSimple.Write(&strTFile, strTFile.GetSize());
1562 fFileSimple.Write(&strFileName, strFileName.GetSize());
1563 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1565 fFileSimple.Write(&strFileName, strFileName.GetSize());
1566 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1568 fFileSimple.fControlBlock->fSeekFileRecord = fFileSimple.fFilePos;
1569 fFileSimple.Write(&fFileSimple.fControlBlock->fFileRecord, fFileSimple.fControlBlock->fFileRecord.GetSize());
1570 fFileSimple.Write(&uuid, uuid.GetSize());
1573 RUInt32BE padding{0};
1574 for (
int i = 0; i < 3; ++i)
1575 fFileSimple.Write(&padding,
sizeof(padding));
1576 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
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
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 checksum)
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.
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 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.
RNTupleFileWriter(std::string_view name)
static 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.
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 fChecksum
The xxhash3 checksum of the serialized other members of the struct (excluding byte count and class ve...
std::uint64_t fSeekFooter
The file offset of the footer excluding the TKey part.
std::uint64_t GetLenFooter() const
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 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.
Long64_t fSeekKey
Location of object on file.
virtual void Create(Int_t nbytes, TFile *f=nullptr)
Create a TKey object of specified size.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
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