42 std::uint16_t fValBE = 0;
43 static std::uint16_t
Swap(std::uint16_t val) {
44 return (val & 0x00FF) << 8 | (val & 0xFF00) >> 8;
47 RUInt16BE() =
default;
48 explicit RUInt16BE(
const std::uint16_t val) : fValBE(
Swap(val)) {}
49 operator std::uint16_t()
const {
52 RUInt16BE&
operator =(
const std::uint16_t val) {
61 std::uint32_t fValBE = 0;
62 static std::uint32_t
Swap(std::uint32_t val) {
63 auto x = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
64 return (
x & 0x00FF00FF) << 8 | (
x & 0xFF00FF00) >> 8;
67 RUInt32BE() =
default;
68 explicit RUInt32BE(
const std::uint32_t val) : fValBE(
Swap(val)) {}
69 operator std::uint32_t()
const {
72 RUInt32BE&
operator =(
const std::uint32_t val) {
81 std::int32_t fValBE = 0;
82 static std::int32_t
Swap(std::int32_t val) {
83 auto x = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
84 return (
x & 0x00FF00FF) << 8 | (
x & 0xFF00FF00) >> 8;
88 explicit RInt32BE(
const std::int32_t val) : fValBE(
Swap(val)) {}
89 operator std::int32_t()
const {
101 std::uint64_t fValBE = 0;
102 static std::uint64_t
Swap(std::uint64_t val) {
103 auto x = (val & 0x00000000FFFFFFFF) << 32 | (val & 0xFFFFFFFF00000000) >> 32;
104 x = (
x & 0x0000FFFF0000FFFF) << 16 | (
x & 0xFFFF0000FFFF0000) >> 16;
105 return (
x & 0x00FF00FF00FF00FF) << 8 | (
x & 0xFF00FF00FF00FF00) >> 8;
108 RUInt64BE() =
default;
109 explicit RUInt64BE(
const std::uint64_t val) : fValBE(
Swap(val)) {}
110 operator std::uint64_t()
const {
113 RUInt64BE&
operator =(
const std::uint64_t val) {
120constexpr std::int32_t ChecksumRNTupleClass() {
121 const char ident[] =
"ROOT::Experimental::RNTuple"
141 for (
unsigned i = 0; i < (
sizeof(ident) - 1); i++)
142 id =
static_cast<std::int32_t
>(
static_cast<std::int64_t
>(
id) * 3 + ident[i]);
152 RTFString() =
default;
153 RTFString(
const std::string &str) {
155 fLName = str.length();
156 memcpy(fData, str.data(), fLName);
158 char GetSize()
const {
return 1 + fLName; }
165 auto now = std::chrono::system_clock::now();
166 auto tt = std::chrono::system_clock::to_time_t(now);
167 auto tm = *localtime(&
tt);
168 fDatetime = (tm.tm_year + 1900 - 1995) << 26 | (tm.tm_mon + 1) << 22 | tm.tm_mday << 17 |
169 tm.tm_hour << 12 | tm.tm_min << 6 | tm.tm_sec;
171 explicit RTFDatetime(RUInt32BE val) : fDatetime(val) {}
177 RUInt16BE fVersion{4};
178 RUInt32BE fObjLen{0};
179 RTFDatetime fDatetime;
180 RUInt16BE fKeyLen{0};
184 RUInt32BE fSeekKey{0};
185 RUInt32BE fSeekPdir{0};
188 RUInt64BE fSeekKey{0};
189 RUInt64BE fSeekPdir{0};
193 std::uint32_t fKeyHeaderSize{18 +
sizeof(fInfoShort)};
195 RTFKey() : fInfoShort() {}
196 RTFKey(std::uint64_t seekKey, std::uint64_t seekPdir,
197 const RTFString &clName,
const RTFString &objName,
const RTFString &titleName,
198 std::uint32_t szObjInMem, std::uint32_t szObjOnDisk = 0)
200 fObjLen = szObjInMem;
201 if ((seekKey >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) ||
202 (seekPdir >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())))
204 fKeyHeaderSize = 18 +
sizeof(fInfoLong);
205 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
206 fInfoLong.fSeekKey = seekKey;
207 fInfoLong.fSeekPdir = seekPdir;
208 fVersion = fVersion + 1000;
210 fKeyHeaderSize = 18 +
sizeof(fInfoShort);
211 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
212 fInfoShort.fSeekKey = seekKey;
213 fInfoShort.fSeekPdir = seekPdir;
215 fNbytes = fKeyLen + ((szObjOnDisk == 0) ? szObjInMem : szObjOnDisk);
218 std::uint32_t GetSize()
const {
225 std::uint32_t GetHeaderSize()
const {
226 if (fVersion >= 1000)
227 return 18 +
sizeof(fInfoLong);
228 return 18 +
sizeof(fInfoShort);
231 std::uint64_t GetSeekKey()
const {
232 if (fVersion >= 1000)
233 return fInfoLong.fSeekKey;
234 return fInfoShort.fSeekKey;
240 char fMagic[4]{
'r',
'o',
'o',
't' };
244 RUInt32BE fBEGIN{100};
248 RUInt32BE fSeekFree{0};
249 RUInt32BE fNbytesFree{0};
251 RUInt32BE fNbytesName{0};
252 unsigned char fUnits{4};
253 RUInt32BE fCompress{0};
254 RUInt32BE fSeekInfo{0};
255 RUInt32BE fNbytesInfo{0};
259 RUInt64BE fSeekFree{0};
260 RUInt32BE fNbytesFree{0};
262 RUInt32BE fNbytesName{0};
263 unsigned char fUnits{8};
264 RUInt32BE fCompress{0};
265 RUInt64BE fSeekInfo{0};
266 RUInt32BE fNbytesInfo{0};
270 RTFHeader() : fInfoShort() {}
271 RTFHeader(
int compression) : fInfoShort() {
272 fInfoShort.fCompress = compression;
276 if (fVersion >= 1000000)
279 std::uint32_t end = fInfoShort.fEND;
280 std::uint32_t seekFree = fInfoShort.fSeekFree;
281 std::uint32_t nbytesFree = fInfoShort.fNbytesFree;
282 std::uint32_t nFree = fInfoShort.fNfree;
283 std::uint32_t nbytesName = fInfoShort.fNbytesName;
284 std::uint32_t compress = fInfoShort.fCompress;
285 std::uint32_t seekInfo = fInfoShort.fSeekInfo;
286 std::uint32_t nbytesInfo = fInfoShort.fNbytesInfo;
287 fInfoLong.fEND = end;
288 fInfoLong.fSeekFree = seekFree;
289 fInfoLong.fNbytesFree = nbytesFree;
290 fInfoLong.fNfree = nFree;
291 fInfoLong.fNbytesName = nbytesName;
292 fInfoLong.fUnits = 8;
293 fInfoLong.fCompress = compress;
294 fInfoLong.fSeekInfo = seekInfo;
295 fInfoLong.fNbytesInfo = nbytesInfo;
296 fVersion = fVersion + 1000000;
299 bool IsBigFile(std::uint64_t offset = 0)
const {
300 return (fVersion >= 1000000) || (offset >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max()));
303 std::uint32_t GetSize()
const {
304 std::uint32_t sizeHead = 4 +
sizeof(fVersion) +
sizeof(fBEGIN);
305 if (IsBigFile())
return sizeHead +
sizeof(fInfoLong);
306 return sizeHead +
sizeof(fInfoShort);
309 std::uint64_t GetEnd()
const {
310 if (IsBigFile())
return fInfoLong.fEND;
311 return fInfoShort.fEND;
314 void SetEnd(std::uint64_t value) {
315 if (IsBigFile(value)) {
317 fInfoLong.fEND = value;
319 fInfoShort.fEND = value;
323 std::uint64_t GetSeekFree()
const {
324 if (IsBigFile())
return fInfoLong.fSeekFree;
325 return fInfoShort.fSeekFree;
328 void SetSeekFree(std::uint64_t value) {
329 if (IsBigFile(value)) {
331 fInfoLong.fSeekFree = value;
333 fInfoShort.fSeekFree = value;
337 void SetNbytesFree(std::uint32_t value) {
339 fInfoLong.fNbytesFree = value;
341 fInfoShort.fNbytesFree = value;
345 void SetNbytesName(std::uint32_t value) {
347 fInfoLong.fNbytesName = value;
349 fInfoShort.fNbytesName = value;
353 std::uint64_t GetSeekInfo()
const {
354 if (IsBigFile())
return fInfoLong.fSeekInfo;
355 return fInfoShort.fSeekInfo;
358 void SetSeekInfo(std::uint64_t value) {
359 if (IsBigFile(value)) {
361 fInfoLong.fSeekInfo = value;
363 fInfoShort.fSeekInfo = value;
367 void SetNbytesInfo(std::uint32_t value) {
369 fInfoLong.fNbytesInfo = value;
371 fInfoShort.fNbytesInfo = value;
375 void SetCompression(std::uint32_t value) {
377 fInfoLong.fCompress = value;
379 fInfoShort.fCompress = value;
387 RUInt16BE fVersion{1};
399 RTFFreeEntry() : fInfoShort() {}
400 void Set(std::uint64_t
first, std::uint64_t last) {
401 if (last >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) {
402 fVersion = fVersion + 1000;
403 fInfoLong.fFirst =
first;
404 fInfoLong.fLast = last;
406 fInfoShort.fFirst =
first;
407 fInfoShort.fLast = last;
410 std::uint32_t GetSize() {
return (fVersion >= 1000) ? 18 : 10; }
415 RUInt16BE fVersion{1};
416 RUInt32BE fUniqueID{0};
418 explicit RTFObject(std::uint32_t bits) : fBits(bits) {}
422struct RTFStreamerElementVersion {
423 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersion) -
sizeof(RUInt32BE))};
424 RUInt16BE fVersion{4};
426 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 10)};
427 RUInt16BE fVersionNamed{1};
428 RTFObject fObjectNamed{0x02000000 | 0x01000000};
430 char fName[8]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n' };
435 RUInt32BE fArrLength{0};
436 RUInt32BE fArrDim{0};
437 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
438 char fLTypeName = 12;
439 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
443struct RTFStreamerElementSize {
444 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSize) -
sizeof(RUInt32BE))};
445 RUInt16BE fVersion{4};
447 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 7)};
448 RUInt16BE fVersionNamed{1};
449 RTFObject fObjectNamed{0x02000000 | 0x01000000};
451 char fName[5]{
'f',
'S',
'i',
'z',
'e' };
456 RUInt32BE fArrLength{0};
457 RUInt32BE fArrDim{0};
458 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
459 char fLTypeName = 12;
460 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
464struct RTFStreamerElementSeekHeader {
465 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekHeader) -
sizeof(RUInt32BE))};
466 RUInt16BE fVersion{4};
468 RUInt32BE fByteCountNamed{0x40000000 |
469 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
470 RUInt16BE fVersionNamed{1};
471 RTFObject fObjectNamed{0x02000000 | 0x01000000};
473 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'H',
'e',
'a',
'd',
'e',
'r' };
478 RUInt32BE fArrLength{0};
479 RUInt32BE fArrDim{0};
480 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
481 char fLTypeName = 13;
482 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
486struct RTFStreamerElementNBytesHeader {
487 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesHeader) -
sizeof(RUInt32BE))};
488 RUInt16BE fVersion{4};
490 RUInt32BE fByteCountNamed{0x40000000 |
491 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
492 RUInt16BE fVersionNamed{1};
493 RTFObject fObjectNamed{0x02000000 | 0x01000000};
495 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'H',
'e',
'a',
'd',
'e',
'r' };
500 RUInt32BE fArrLength{0};
501 RUInt32BE fArrDim{0};
502 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
503 char fLTypeName = 12;
504 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
508struct RTFStreamerElementLenHeader {
509 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenHeader) -
sizeof(RUInt32BE))};
510 RUInt16BE fVersion{4};
512 RUInt32BE fByteCountNamed{0x40000000 |
513 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
514 RUInt16BE fVersionNamed{1};
515 RTFObject fObjectNamed{0x02000000 | 0x01000000};
517 char fName[10]{
'f',
'L',
'e',
'n',
'H',
'e',
'a',
'd',
'e',
'r' };
522 RUInt32BE fArrLength{0};
523 RUInt32BE fArrDim{0};
524 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
525 char fLTypeName = 12;
526 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
530struct RTFStreamerElementSeekFooter {
531 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekFooter) -
sizeof(RUInt32BE))};
532 RUInt16BE fVersion{4};
534 RUInt32BE fByteCountNamed{0x40000000 |
535 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
536 RUInt16BE fVersionNamed{1};
537 RTFObject fObjectNamed{0x02000000 | 0x01000000};
539 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'F',
'o',
'o',
't',
'e',
'r' };
544 RUInt32BE fArrLength{0};
545 RUInt32BE fArrDim{0};
546 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
547 char fLTypeName = 13;
548 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
552struct RTFStreamerElementNBytesFooter {
553 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesFooter) -
sizeof(RUInt32BE))};
554 RUInt16BE fVersion{4};
556 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
557 RUInt16BE fVersionNamed{1};
558 RTFObject fObjectNamed{0x02000000 | 0x01000000};
560 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'F',
'o',
'o',
't',
'e',
'r' };
565 RUInt32BE fArrLength{0};
566 RUInt32BE fArrDim{0};
567 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
568 char fLTypeName = 12;
569 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
573struct RTFStreamerElementLenFooter {
574 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenFooter) -
sizeof(RUInt32BE))};
575 RUInt16BE fVersion{4};
577 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
578 RUInt16BE fVersionNamed{1};
579 RTFObject fObjectNamed{0x02000000 | 0x01000000};
581 char fName[10]{
'f',
'L',
'e',
'n',
'F',
'o',
'o',
't',
'e',
'r' };
586 RUInt32BE fArrLength{0};
587 RUInt32BE fArrDim{0};
588 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
589 char fLTypeName = 12;
590 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
594struct RTFStreamerElementReserved {
595 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementReserved) -
sizeof(RUInt32BE))};
596 RUInt16BE fVersion{4};
598 RUInt32BE fByteCountNamed{0x40000000 |
599 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 11)};
600 RUInt16BE fVersionNamed{1};
601 RTFObject fObjectNamed{0x02000000 | 0x01000000};
603 char fName[9]{
'f',
'R',
'e',
's',
'e',
'r',
'v',
'e',
'd' };
608 RUInt32BE fArrLength{0};
609 RUInt32BE fArrDim{0};
610 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
611 char fLTypeName = 13;
612 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
616struct RTFStreamerVersion {
617 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersion) -
sizeof(RUInt32BE))};
618 RUInt32BE fNewClassTag{0xffffffff};
619 char fClassName[19]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'B',
'a',
's',
'i',
'c',
'T',
'y',
'p',
'e',
'\0'};
620 RUInt32BE fByteCountRemaining{0x40000000 |
621 (
sizeof(RTFStreamerVersion) - 2 *
sizeof(RUInt32BE) - 19 -
sizeof(RUInt32BE))};
622 RUInt16BE fVersion{2};
623 RTFStreamerElementVersion fStreamerElementVersion;
627struct RTFStreamerSize {
628 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSize) -
sizeof(RUInt32BE))};
629 RUInt32BE fClassTag{0x80000000};
630 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSize) - 3 *
sizeof(RUInt32BE))};
631 RUInt16BE fVersion{2};
632 RTFStreamerElementSize fStreamerElementSize;
636struct RTFStreamerSeekHeader {
637 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekHeader) -
sizeof(RUInt32BE))};
638 RUInt32BE fClassTag{0x80000000};
639 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekHeader) - 3 *
sizeof(RUInt32BE))};
640 RUInt16BE fVersion{2};
641 RTFStreamerElementSeekHeader fStreamerElementSeekHeader;
645struct RTFStreamerNBytesHeader {
646 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) -
sizeof(RUInt32BE))};
647 RUInt32BE fClassTag{0x80000000};
648 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) - 3 *
sizeof(RUInt32BE))};
649 RUInt16BE fVersion{2};
650 RTFStreamerElementNBytesHeader fStreamerElementNBytesHeader;
654struct RTFStreamerLenHeader {
655 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenHeader) -
sizeof(RUInt32BE))};
656 RUInt32BE fClassTag{0x80000000};
657 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenHeader) - 3 *
sizeof(RUInt32BE))};
658 RUInt16BE fVersion{2};
659 RTFStreamerElementLenHeader fStreamerElementLenHeader;
663struct RTFStreamerSeekFooter {
664 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekFooter) -
sizeof(RUInt32BE))};
665 RUInt32BE fClassTag{0x80000000};
666 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekFooter) - 3 *
sizeof(RUInt32BE))};
667 RUInt16BE fVersion{2};
668 RTFStreamerElementSeekFooter fStreamerElementSeekFooter;
672struct RTFStreamerNBytesFooter {
673 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) -
sizeof(RUInt32BE))};
674 RUInt32BE fClassTag{0x80000000};
675 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) - 3 *
sizeof(RUInt32BE))};
676 RUInt16BE fVersion{2};
677 RTFStreamerElementNBytesFooter fStreamerElementNBytesFooter;
681struct RTFStreamerLenFooter {
682 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenFooter) -
sizeof(RUInt32BE))};
683 RUInt32BE fClassTag{0x80000000};
684 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenFooter) - 3 *
sizeof(RUInt32BE))};
685 RUInt16BE fVersion{2};
686 RTFStreamerElementLenFooter fStreamerElementLenFooter;
690struct RTFStreamerReserved {
691 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerReserved) -
sizeof(RUInt32BE))};
692 RUInt32BE fClassTag{0x80000000};
693 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerReserved) - 3 *
sizeof(RUInt32BE))};
694 RUInt16BE fVersion{2};
695 RTFStreamerElementReserved fStreamerElementReserved;
699struct RTFStreamerInfoObject {
700 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoObject) -
sizeof(fByteCount))};
701 RUInt32BE fNewClassTag{0xffffffff};
702 char fClassName[14]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'I',
'n',
'f',
'o',
'\0' };
703 RUInt32BE fByteCountRemaining{0x40000000 |
704 (
sizeof(RTFStreamerInfoObject) - 2 *
sizeof(RUInt32BE) - 14 -
sizeof(RUInt32BE))};
705 RUInt16BE fVersion{9};
707 RUInt32BE fByteCountNamed{0x40000000 |
708 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 29 )};
709 RUInt16BE fVersionNamed{1};
710 RTFObject fObjectNamed{0x02000000 | 0x01000000 | 0x00010000};
712 char fName[27]{
'R',
'O',
'O',
'T',
':',
':',
713 'E',
'x',
'p',
'e',
'r',
'i',
'm',
'e',
'n',
't',
'a',
'l',
':',
':',
714 'R',
'N',
'T',
'u',
'p',
'l',
'e'};
717 RInt32BE fChecksum{ChecksumRNTupleClass()};
718 RUInt32BE fVersionRNTuple{1};
720 RUInt32BE fByteCountObjArr{0x40000000 |
721 (
sizeof(RUInt32BE) + 10 +
sizeof(RUInt32BE) +
722 sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2*
sizeof(RUInt32BE) +
723 sizeof(fStreamers))};
724 RUInt32BE fNewClassTagObjArray{0xffffffff};
725 char fClassNameObjArray[10]{
'T',
'O',
'b',
'j',
'A',
'r',
'r',
'a',
'y',
'\0'};
726 RUInt32BE fByteCountObjArrRemaining{0x40000000 |
727 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2*
sizeof(RUInt32BE) +
728 sizeof(fStreamers))};
729 RUInt16BE fVersionObjArr{3};
730 RTFObject fObjectObjArr{0x02000000};
733 RUInt32BE fNObjects{9};
734 RUInt32BE fLowerBound{0};
737 RTFStreamerVersion fStreamerVersion;
738 RTFStreamerSize fStreamerSize;
739 RTFStreamerSeekHeader fStreamerSeekHeader;
740 RTFStreamerNBytesHeader fStreamerNBytesHeader;
741 RTFStreamerLenHeader fStreamerLenHeader;
742 RTFStreamerSeekFooter fStreamerSeekFooter;
743 RTFStreamerNBytesFooter fStreamerNBytesFooter;
744 RTFStreamerLenFooter fStreamerLenFooter;
745 RTFStreamerReserved fStreamerReserved;
750struct RTFStreamerInfoList {
751 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoList) -
sizeof(fByteCount))};
752 RUInt16BE fVersion{5};
753 RTFObject fObject{0x02000000};
755 RUInt32BE fNObjects{1};
756 RTFStreamerInfoObject fStreamerInfo;
759 std::uint32_t GetSize()
const {
return sizeof(RTFStreamerInfoList); }
765 std::uint32_t GetSize()
const {
return sizeof(RTFKeyList); }
766 explicit RTFKeyList(std::uint32_t nKeys) : fNKeys(nKeys) {}
775 RUInt32BE fNBytesKeys{0};
776 RUInt32BE fNBytesName{0};
780 RUInt32BE fSeekDir{100};
781 RUInt32BE fSeekParent{0};
782 RUInt32BE fSeekKeys{0};
785 RUInt64BE fSeekDir{100};
786 RUInt64BE fSeekParent{0};
787 RUInt64BE fSeekKeys{0};
791 RTFFile() : fInfoShort() {}
793 std::uint32_t GetSize(std::uint32_t versionKey = 0)
const {
794 if (versionKey >= 1000)
795 return 18 +
sizeof(fInfoLong);
796 return 18 +
sizeof(fInfoShort);
799 std::uint64_t GetSeekKeys(std::uint32_t versionKey = 0)
const {
800 if (versionKey >= 1000)
801 return fInfoLong.fSeekKeys;
802 return fInfoShort.fSeekKeys;
808 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFNTuple) -
sizeof(fByteCount))};
809 RUInt16BE fVersionClass{0};
810 RInt32BE fChecksum{ChecksumRNTupleClass()};
811 RUInt32BE fVersionInternal{0};
813 RUInt64BE fSeekHeader{0};
814 RUInt32BE fNBytesHeader{0};
815 RUInt32BE fLenHeader{0};
816 RUInt64BE fSeekFooter{0};
817 RUInt32BE fNBytesFooter{0};
818 RUInt32BE fLenFooter{0};
819 RUInt64BE fReserved{0};
821 RTFNTuple() =
default;
823 fVersionInternal = inMemoryNTuple.
fVersion;
833 std::uint32_t GetSize()
const {
return sizeof(RTFNTuple); }
848 output <<
"RTFNTuple {\n";
849 output <<
" fByteCount: " << fByteCount <<
",\n";
850 output <<
" fVersionClass: " << fVersionClass <<
",\n";
851 output <<
" fChecksum: " << fChecksum <<
",\n";
852 output <<
" fVersionInternal: " << fVersionInternal <<
",\n";
854 output <<
" fSeekHeader: " << fSeekHeader <<
",\n";
855 output <<
" fNBytesHeader: " << fNBytesHeader <<
",\n";
856 output <<
" fLenHeader: " << fLenHeader <<
",\n";
857 output <<
" fSeekFooter: " << fSeekFooter <<
",\n";
858 output <<
" fNBytesFooter: " << fNBytesFooter <<
",\n";
859 output <<
" fLenFooter: " << fLenFooter <<
",\n";
860 output <<
" fReserved: " << fReserved <<
",\n";
866struct RBareFileHeader {
867 char fMagic[7]{
'r',
'n',
't',
'u',
'p',
'l',
'e' };
871 RUInt32BE fFormatVersion{1};
872 RUInt32BE fCompress{0};
879static constexpr char const *kBlobClassName =
"RBlob";
881static constexpr char const *kNTupleClassName =
"ROOT::Experimental::RNTuple";
885class RKeyBlob :
public TKey {
888 fClassName = kBlobClassName;
889 fKeylen += strlen(kBlobClassName);
893 void Reserve(
size_t nbytes, std::uint64_t *seekKey)
904namespace Experimental {
927 if (std::string(ident, 4) ==
"root")
928 return GetNTupleProper(ntupleName);
930 return GetNTupleBare(ntupleName);
937 RTFHeader fileHeader;
938 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
942 ReadBuffer(&key,
sizeof(key), fileHeader.fBEGIN);
943 auto offset = fileHeader.fBEGIN + key.fKeyLen;
945 offset +=
name.GetSize();
947 offset +=
name.GetSize();
952 offset =
file.GetSeekKeys(key.fVersion);
954 offset += key.fKeyLen;
956 offset +=
sizeof(nKeys);
958 for (
unsigned int i = 0; i < nKeys; ++i) {
960 auto offsetNextKey = offset + key.fKeyLen;
962 offset += key.GetHeaderSize();
965 if (std::string_view(
name.fData,
name.fLName) != kNTupleClassName) {
966 offset = offsetNextKey;
969 offset +=
name.GetSize();
972 if (std::string_view(
name.fData,
name.fLName) == ntupleName) {
976 offset = offsetNextKey;
979 return R__FAIL(
"no RNTuple named '" + std::string(ntupleName)
980 +
"' in file '" + fRawFile->GetUrl() +
"'");
983 ReadBuffer(&key,
sizeof(key), key.GetSeekKey());
984 offset = key.GetSeekKey() + key.fKeyLen;
987 return ntuple.ToRNTuple();
993 RBareFileHeader fileHeader;
994 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
996 auto offset =
sizeof(fileHeader);
999 std::string_view foundName(
name.fData,
name.fLName);
1000 if (foundName != ntupleName) {
1001 return R__FAIL(
"expected RNTuple named '" + std::string(ntupleName)
1002 +
"' but instead found '" + std::string(foundName)
1003 +
"' in file '" + fRawFile->GetUrl() +
"'");
1005 offset +=
name.GetSize();
1009 return ntuple.ToRNTuple();
1015 auto nread = fRawFile->ReadAt(buffer, nbytes, offset);
1031 const void *buffer,
size_t nbytes, std::int64_t offset)
1035 if ((offset >= 0) && (
static_cast<std::uint64_t
>(offset) != fFilePos)) {
1037 retval = fseeko64(fFile, offset, SEEK_SET);
1039 retval = fseek(fFile, offset, SEEK_SET);
1044 retval = fwrite(buffer, 1, nbytes, fFile);
1051 const void *buffer, std::size_t nbytes, std::size_t len, std::int64_t offset,
1052 std::uint64_t directoryOffset,
1053 const std::string &className,
1054 const std::string &objectName,
1055 const std::string &title)
1059 RTFString strClass{className};
1060 RTFString strObject{objectName};
1061 RTFString strTitle{title};
1063 RTFKey key(offset, directoryOffset, strClass, strObject, strTitle, len, nbytes);
1064 Write(&key, key.fKeyHeaderSize, offset);
1065 Write(&strClass, strClass.GetSize());
1066 Write(&strObject, strObject.GetSize());
1067 Write(&strTitle, strTitle.GetSize());
1068 auto offsetData = fFilePos;
1070 Write(buffer, nbytes);
1080 const void *buffer,
size_t nbytes, std::int64_t offset)
1083 fFile->Seek(offset);
1084 bool rv = fFile->WriteBuffer((
char *)(buffer), nbytes);
1090 const void *buffer,
size_t nbytes,
size_t len)
1092 std::uint64_t offsetKey;
1093 RKeyBlob keyBlob(fFile);
1094 keyBlob.Reserve(nbytes, &offsetKey);
1096 auto offset = offsetKey;
1097 RTFString strClass{kBlobClassName};
1098 RTFString strObject;
1100 RTFKey keyHeader(offset, offset, strClass, strObject, strTitle, len, nbytes);
1102 Write(&keyHeader, keyHeader.fKeyHeaderSize, offset);
1103 offset += keyHeader.fKeyHeaderSize;
1104 Write(&strClass, strClass.GetSize(), offset);
1105 offset += strClass.GetSize();
1106 Write(&strObject, strObject.GetSize(), offset);
1107 offset += strObject.GetSize();
1108 Write(&strTitle, strTitle.GetSize(), offset);
1109 offset += strTitle.GetSize();
1110 auto offsetData = offset;
1111 Write(buffer, nbytes, offset);
1133 std::string_view ntupleName, std::string_view path,
int defaultCompression,
ENTupleContainerFormat containerFormat)
1135 std::string fileName(path);
1136 size_t idxDirSep = fileName.find_last_of(
"\\/");
1137 if (idxDirSep != std::string::npos) {
1138 fileName.erase(0, idxDirSep + 1);
1141 FILE *fileStream = fopen64(std::string(path.data(), path.size()).c_str(),
"wb");
1143 FILE *fileStream = fopen(std::string(path.data(), path.size()).c_str(),
"wb");
1148 writer->fFileSimple.fFile = fileStream;
1149 writer->fFileName = fileName;
1151 switch (containerFormat) {
1153 writer->WriteTFileSkeleton(defaultCompression);
1157 writer->WriteBareFileSkeleton(defaultCompression);
1160 R__ASSERT(
false &&
"Internal error: unhandled container format");
1168 std::string_view ntupleName, std::string_view path, std::unique_ptr<TFile> &
file)
1170 file = std::unique_ptr<TFile>(
TFile::Open(std::string(path.data(), path.size()).c_str(),
"RECREATE"));
1180 std::string_view ntupleName,
TFile &
file)
1192 fFileProper.fFile->WriteObject(&fNTupleAnchor, fNTupleName.c_str());
1193 fFileProper.fFile->Write();
1199 RTFNTuple ntupleOnDisk(fNTupleAnchor);
1202 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize(), fFileSimple.fControlBlock->fSeekNTuple);
1203 fflush(fFileSimple.fFile);
1207 fFileSimple.fControlBlock->fHeader.SetSeekFree(fFileSimple.fFilePos);
1209 RTFFreeEntry freeEntry;
1210 RTFKey keyFreeList(fFileSimple.fControlBlock->fHeader.GetSeekFree(), 100,
1211 strEmpty, strEmpty, strEmpty, freeEntry.GetSize());
1212 std::uint64_t firstFree = fFileSimple.fControlBlock->fHeader.GetSeekFree() + keyFreeList.GetSize();
1213 freeEntry.Set(firstFree, std::max(2000000000ULL, ((firstFree / 1000000000ULL) + 1) * 1000000000ULL));
1214 fFileSimple.WriteKey(
1215 &freeEntry, freeEntry.GetSize(), freeEntry.GetSize(), fFileSimple.fControlBlock->fHeader.GetSeekFree(),
1217 fFileSimple.fControlBlock->fHeader.SetNbytesFree(fFileSimple.fFilePos -
1218 fFileSimple.fControlBlock->fHeader.GetSeekFree());
1219 fFileSimple.fControlBlock->fHeader.SetEnd(fFileSimple.fFilePos);
1221 auto szNTuple = ntupleOnDisk.GetSize();
1222 fFileSimple.WriteKey(&ntupleOnDisk, szNTuple, szNTuple, fFileSimple.fControlBlock->fSeekNTuple, 100,
1223 kNTupleClassName, fNTupleName);
1225 fFileSimple.Write(&fFileSimple.fControlBlock->fHeader, fFileSimple.fControlBlock->fHeader.GetSize(), 0);
1226 fflush(fFileSimple.fFile);
1232 std::uint64_t offset;
1235 offset = fFileSimple.fFilePos;
1236 fFileSimple.Write(data, nbytes);
1238 offset = fFileSimple.WriteKey(data, nbytes, len, -1, 100, kBlobClassName);
1241 offset = fFileProper.WriteKey(data, nbytes, len);
1248 const void *data,
size_t nbytes,
size_t lenHeader)
1250 auto offset = WriteBlob(data, nbytes, lenHeader);
1251 fNTupleAnchor.fLenHeader = lenHeader;
1252 fNTupleAnchor.fNBytesHeader = nbytes;
1253 fNTupleAnchor.fSeekHeader = offset;
1259 const void *data,
size_t nbytes,
size_t lenFooter)
1261 auto offset = WriteBlob(data, nbytes, lenFooter);
1262 fNTupleAnchor.fLenFooter = lenFooter;
1263 fNTupleAnchor.fNBytesFooter = nbytes;
1264 fNTupleAnchor.fSeekFooter = offset;
1271 RBareFileHeader bareHeader;
1272 bareHeader.fCompress = defaultCompression;
1273 fFileSimple.Write(&bareHeader,
sizeof(bareHeader), 0);
1274 RTFString ntupleName{fNTupleName};
1275 fFileSimple.Write(&ntupleName, ntupleName.GetSize());
1278 RTFNTuple ntupleOnDisk;
1279 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fFilePos;
1280 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize());
1286 RTFString strTFile{
"TFile"};
1287 RTFString strFileName{fFileName};
1288 RTFString strTList{
"TList"};
1289 RTFString strStreamerInfo{
"StreamerInfo"};
1290 RTFString strStreamerTitle{
"Doubly linked list"};
1291 RTFString strRNTupleClass{
"ROOT::Experimental::RNTuple"};
1292 RTFString strRNTupleName{fNTupleName};
1295 fFileSimple.fControlBlock->fHeader = RTFHeader(defaultCompression);
1299 RTFKey keyRoot(100, 0, strTFile, strFileName, strEmpty,
1300 fileRoot.GetSize() + strFileName.GetSize() + strEmpty.GetSize());
1301 std::uint32_t nbytesName = keyRoot.fKeyLen + strFileName.GetSize() + 1;
1302 fileRoot.fNBytesName = nbytesName;
1303 fFileSimple.fControlBlock->fHeader.SetNbytesName(nbytesName);
1308 fFileSimple.fControlBlock->fHeader.SetSeekInfo(100 + keyRoot.GetSize());
1309 RTFKey keyStreamerInfo(
1310 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100, strTList, strStreamerInfo, strStreamerTitle, 0);
1311 RTFStreamerInfoList streamerInfo;
1312 auto classTagOffset = keyStreamerInfo.fKeyLen +
1313 offsetof(
struct RTFStreamerInfoList, fStreamerInfo) +
1314 offsetof(
struct RTFStreamerInfoObject, fStreamers) +
1315 offsetof(
struct RTFStreamerVersion, fNewClassTag) + 2;
1316 streamerInfo.fStreamerInfo.fStreamers.fStreamerSize.fClassTag = 0x80000000 | classTagOffset;
1317 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekHeader.fClassTag = 0x80000000 | classTagOffset;
1318 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesHeader.fClassTag = 0x80000000 | classTagOffset;
1319 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenHeader.fClassTag = 0x80000000 | classTagOffset;
1320 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekFooter.fClassTag = 0x80000000 | classTagOffset;
1321 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesFooter.fClassTag = 0x80000000 | classTagOffset;
1322 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenFooter.fClassTag = 0x80000000 | classTagOffset;
1323 streamerInfo.fStreamerInfo.fStreamers.fStreamerReserved.fClassTag = 0x80000000 | classTagOffset;
1325 auto szStreamerInfo = compressor.
Zip(&streamerInfo, streamerInfo.GetSize(), 1);
1326 fFileSimple.WriteKey(compressor.
GetZipBuffer(), szStreamerInfo, streamerInfo.GetSize(),
1327 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100,
1328 "TList",
"StreamerInfo",
"Doubly linked list");
1329 fFileSimple.fControlBlock->fHeader.SetNbytesInfo(
1330 fFileSimple.fFilePos - fFileSimple.fControlBlock->fHeader.GetSeekInfo());
1333 RTFNTuple ntupleOnDisk;
1334 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fFilePos;
1335 RTFKey keyRNTuple(fFileSimple.fControlBlock->fSeekNTuple, 100, strRNTupleClass, strRNTupleName, strEmpty,
1336 ntupleOnDisk.GetSize());
1337 fFileSimple.WriteKey(&ntupleOnDisk, ntupleOnDisk.GetSize(), ntupleOnDisk.GetSize(),
1338 fFileSimple.fControlBlock->fSeekNTuple, 100,
"ROOT::Experimental::RNTUple", fNTupleName,
"");
1341 fileRoot.fInfoShort.fSeekKeys = fFileSimple.fFilePos;
1342 RTFKeyList keyList{1};
1343 RTFKey keyKeyList(fileRoot.GetSeekKeys(), 100, strEmpty, strEmpty, strEmpty, keyList.GetSize() + keyRNTuple.fKeyLen);
1344 fFileSimple.Write(&keyKeyList, keyKeyList.fKeyHeaderSize, fileRoot.GetSeekKeys());
1345 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1346 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1347 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1348 fFileSimple.Write(&keyList, keyList.GetSize());
1349 fFileSimple.Write(&keyRNTuple, keyRNTuple.fKeyHeaderSize);
1350 fFileSimple.Write(&strRNTupleClass, strRNTupleClass.GetSize());
1351 fFileSimple.Write(&strRNTupleName, strRNTupleName.GetSize());
1352 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1353 fileRoot.fNBytesKeys = fFileSimple.fFilePos - fileRoot.GetSeekKeys();
1355 auto tail = fFileSimple.fFilePos;
1356 fFileSimple.Write(&keyRoot, keyRoot.fKeyHeaderSize, 100);
1357 fFileSimple.Write(&strTFile, strTFile.GetSize());
1358 fFileSimple.Write(&strFileName, strFileName.GetSize());
1359 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1360 fFileSimple.Write(&strFileName, strFileName.GetSize());
1361 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1362 fFileSimple.Write(&fileRoot, fileRoot.GetSize());
1363 fFileSimple.fFilePos = tail;
1365 auto retval = fseeko64(fFileSimple.fFile, tail, SEEK_SET);
1367 auto retval = fseek(fFileSimple.fFile, tail, SEEK_SET);
1370 fFileSimple.fFilePos = tail;
#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
Binding & operator=(OUT(*fun)(void))
virtual void ReadBuffer(char *&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.
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.
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 Commit()
Writes the RNTuple key to the file so that the header and footer keys can be found.
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.
static RNTupleFileWriter * Recreate(std::string_view ntupleName, std::string_view path, int defaultCompression, ENTupleContainerFormat 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 records that constitute an empty file.
void WriteBareFileSkeleton(int defaultCompression)
For a bare file, which is necessarily written by a C file stream, write file header.
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...
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 a suite of consecutive data records (TKey instances) with a well defined format.
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
virtual void Create(Int_t nbytes, TFile *f=0)
Create a TKey object of specified size.
Long64_t fSeekKey
Location of object on file.
void Print(std::ostream &os, const OptionType &opt)
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 needs...
std::uint32_t fSeekNTuple
Entry point for an RNTuple in a ROOT file.
std::uint64_t fSeekFooter
The file offset of the footer excluding the TKey part.
std::uint32_t fLenHeader
The size of the uncompressed ntuple header.
std::uint64_t fReserved
Currently unused, reserved for later use.
std::uint32_t fVersion
Allows for evolving the struct in future versions.
std::uint32_t fNBytesHeader
The size of the compressed ntuple header.
std::uint32_t fSize
Allows for skipping the struct.
std::uint32_t fNBytesFooter
The size of the compressed ntuple footer.
std::uint32_t fLenFooter
The size of the uncompressed ntuple footer.
std::uint64_t fSeekHeader
The file offset of the header excluding the TKey part.
static void output(int code)