40 std::uint16_t fValBE = 0;
41 static std::uint16_t
Swap(std::uint16_t val) {
42 return (val & 0x00FF) << 8 | (val & 0xFF00) >> 8;
45 RUInt16BE() =
default;
46 explicit RUInt16BE(
const std::uint16_t val) : fValBE(
Swap(val)) {}
47 operator std::uint16_t()
const {
50 RUInt16BE&
operator =(
const std::uint16_t val) {
59 std::uint32_t fValBE = 0;
60 static std::uint32_t
Swap(std::uint32_t val) {
61 auto x = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
62 return (
x & 0x00FF00FF) << 8 | (
x & 0xFF00FF00) >> 8;
65 RUInt32BE() =
default;
66 explicit RUInt32BE(
const std::uint32_t val) : fValBE(
Swap(val)) {}
67 operator std::uint32_t()
const {
70 RUInt32BE&
operator =(
const std::uint32_t val) {
79 std::int32_t fValBE = 0;
80 static std::int32_t
Swap(std::int32_t val) {
81 auto x = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16;
82 return (
x & 0x00FF00FF) << 8 | (
x & 0xFF00FF00) >> 8;
86 explicit RInt32BE(
const std::int32_t val) : fValBE(
Swap(val)) {}
87 operator std::int32_t()
const {
99 std::uint64_t fValBE = 0;
100 static std::uint64_t
Swap(std::uint64_t val) {
101 auto x = (val & 0x00000000FFFFFFFF) << 32 | (val & 0xFFFFFFFF00000000) >> 32;
102 x = (
x & 0x0000FFFF0000FFFF) << 16 | (
x & 0xFFFF0000FFFF0000) >> 16;
103 return (
x & 0x00FF00FF00FF00FF) << 8 | (
x & 0xFF00FF00FF00FF00) >> 8;
106 RUInt64BE() =
default;
107 explicit RUInt64BE(
const std::uint64_t val) : fValBE(
Swap(val)) {}
108 operator std::uint64_t()
const {
111 RUInt64BE&
operator =(
const std::uint64_t val) {
118constexpr std::int32_t ChecksumRNTupleClass() {
119 const char ident[] =
"ROOT::Experimental::RNTuple"
139 for (
unsigned i = 0; i < (
sizeof(ident) - 1); i++)
140 id =
static_cast<std::int32_t
>(
static_cast<std::int64_t
>(
id) * 3 + ident[i]);
150 RTFString() =
default;
151 RTFString(
const std::string &str) {
153 fLName = str.length();
154 memcpy(fData, str.data(), fLName);
156 char GetSize()
const {
return 1 + fLName; }
163 auto now = std::chrono::system_clock::now();
164 auto tt = std::chrono::system_clock::to_time_t(now);
165 auto tm = *localtime(&
tt);
166 fDatetime = (tm.tm_year + 1900 - 1995) << 26 | (tm.tm_mon + 1) << 22 | tm.tm_mday << 17 |
167 tm.tm_hour << 12 | tm.tm_min << 6 | tm.tm_sec;
169 explicit RTFDatetime(RUInt32BE val) : fDatetime(val) {}
175 RUInt16BE fVersion{4};
176 RUInt32BE fObjLen{0};
177 RTFDatetime fDatetime;
178 RUInt16BE fKeyLen{0};
182 RUInt32BE fSeekKey{0};
183 RUInt32BE fSeekPdir{0};
186 RUInt64BE fSeekKey{0};
187 RUInt64BE fSeekPdir{0};
191 std::uint32_t fKeyHeaderSize{18 +
sizeof(fInfoShort)};
193 RTFKey() : fInfoShort() {}
194 RTFKey(std::uint64_t seekKey, std::uint64_t seekPdir,
195 const RTFString &clName,
const RTFString &objName,
const RTFString &titleName,
196 std::uint32_t szObjInMem, std::uint32_t szObjOnDisk = 0)
198 fObjLen = szObjInMem;
199 if ((seekKey >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) ||
200 (seekPdir >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())))
202 fKeyHeaderSize = 18 +
sizeof(fInfoLong);
203 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
204 fInfoLong.fSeekKey = seekKey;
205 fInfoLong.fSeekPdir = seekPdir;
206 fVersion = fVersion + 1000;
208 fKeyHeaderSize = 18 +
sizeof(fInfoShort);
209 fKeyLen = fKeyHeaderSize + clName.GetSize() + objName.GetSize() + titleName.GetSize();
210 fInfoShort.fSeekKey = seekKey;
211 fInfoShort.fSeekPdir = seekPdir;
213 fNbytes = fKeyLen + ((szObjOnDisk == 0) ? szObjInMem : szObjOnDisk);
216 std::uint32_t GetSize()
const {
223 std::uint32_t GetHeaderSize()
const {
224 if (fVersion >= 1000)
225 return 18 +
sizeof(fInfoLong);
226 return 18 +
sizeof(fInfoShort);
229 std::uint64_t GetSeekKey()
const {
230 if (fVersion >= 1000)
231 return fInfoLong.fSeekKey;
232 return fInfoShort.fSeekKey;
238 char fMagic[4]{
'r',
'o',
'o',
't' };
242 RUInt32BE fBEGIN{100};
246 RUInt32BE fSeekFree{0};
247 RUInt32BE fNbytesFree{0};
249 RUInt32BE fNbytesName{0};
250 unsigned char fUnits{4};
251 RUInt32BE fCompress{0};
252 RUInt32BE fSeekInfo{0};
253 RUInt32BE fNbytesInfo{0};
257 RUInt64BE fSeekFree{0};
258 RUInt32BE fNbytesFree{0};
260 RUInt32BE fNbytesName{0};
261 unsigned char fUnits{8};
262 RUInt32BE fCompress{0};
263 RUInt64BE fSeekInfo{0};
264 RUInt32BE fNbytesInfo{0};
268 RTFHeader() : fInfoShort() {}
269 RTFHeader(
int compression) : fInfoShort() {
270 fInfoShort.fCompress = compression;
274 if (fVersion >= 1000000)
277 std::uint32_t end = fInfoShort.fEND;
278 std::uint32_t seekFree = fInfoShort.fSeekFree;
279 std::uint32_t nbytesFree = fInfoShort.fNbytesFree;
280 std::uint32_t nFree = fInfoShort.fNfree;
281 std::uint32_t nbytesName = fInfoShort.fNbytesName;
282 std::uint32_t compress = fInfoShort.fCompress;
283 std::uint32_t seekInfo = fInfoShort.fSeekInfo;
284 std::uint32_t nbytesInfo = fInfoShort.fNbytesInfo;
285 fInfoLong.fEND = end;
286 fInfoLong.fSeekFree = seekFree;
287 fInfoLong.fNbytesFree = nbytesFree;
288 fInfoLong.fNfree = nFree;
289 fInfoLong.fNbytesName = nbytesName;
290 fInfoLong.fUnits = 8;
291 fInfoLong.fCompress = compress;
292 fInfoLong.fSeekInfo = seekInfo;
293 fInfoLong.fNbytesInfo = nbytesInfo;
294 fVersion = fVersion + 1000000;
297 bool IsBigFile(std::uint64_t offset = 0)
const {
298 return (fVersion >= 1000000) || (offset >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max()));
301 std::uint32_t GetSize()
const {
302 std::uint32_t sizeHead = 4 +
sizeof(fVersion) +
sizeof(fBEGIN);
303 if (IsBigFile())
return sizeHead +
sizeof(fInfoLong);
304 return sizeHead +
sizeof(fInfoShort);
307 std::uint64_t GetEnd()
const {
308 if (IsBigFile())
return fInfoLong.fEND;
309 return fInfoShort.fEND;
312 void SetEnd(std::uint64_t value) {
313 if (IsBigFile(value)) {
315 fInfoLong.fEND = value;
317 fInfoShort.fEND = value;
321 std::uint64_t GetSeekFree()
const {
322 if (IsBigFile())
return fInfoLong.fSeekFree;
323 return fInfoShort.fSeekFree;
326 void SetSeekFree(std::uint64_t value) {
327 if (IsBigFile(value)) {
329 fInfoLong.fSeekFree = value;
331 fInfoShort.fSeekFree = value;
335 void SetNbytesFree(std::uint32_t value) {
337 fInfoLong.fNbytesFree = value;
339 fInfoShort.fNbytesFree = value;
343 void SetNbytesName(std::uint32_t value) {
345 fInfoLong.fNbytesName = value;
347 fInfoShort.fNbytesName = value;
351 std::uint64_t GetSeekInfo()
const {
352 if (IsBigFile())
return fInfoLong.fSeekInfo;
353 return fInfoShort.fSeekInfo;
356 void SetSeekInfo(std::uint64_t value) {
357 if (IsBigFile(value)) {
359 fInfoLong.fSeekInfo = value;
361 fInfoShort.fSeekInfo = value;
365 void SetNbytesInfo(std::uint32_t value) {
367 fInfoLong.fNbytesInfo = value;
369 fInfoShort.fNbytesInfo = value;
373 void SetCompression(std::uint32_t value) {
375 fInfoLong.fCompress = value;
377 fInfoShort.fCompress = value;
385 RUInt16BE fVersion{1};
397 RTFFreeEntry() : fInfoShort() {}
398 void Set(std::uint64_t
first, std::uint64_t last) {
399 if (last >
static_cast<unsigned int>(std::numeric_limits<std::int32_t>::max())) {
400 fVersion = fVersion + 1000;
401 fInfoLong.fFirst =
first;
402 fInfoLong.fLast = last;
404 fInfoShort.fFirst =
first;
405 fInfoShort.fLast = last;
408 std::uint32_t GetSize() {
return (fVersion >= 1000) ? 18 : 10; }
413 RUInt16BE fVersion{1};
414 RUInt32BE fUniqueID{0};
416 explicit RTFObject(std::uint32_t bits) : fBits(bits) {}
420struct RTFStreamerElementVersion {
421 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementVersion) -
sizeof(RUInt32BE))};
422 RUInt16BE fVersion{4};
424 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 10)};
425 RUInt16BE fVersionNamed{1};
426 RTFObject fObjectNamed{0x02000000 | 0x01000000};
428 char fName[8]{
'f',
'V',
'e',
'r',
's',
'i',
'o',
'n' };
433 RUInt32BE fArrLength{0};
434 RUInt32BE fArrDim{0};
435 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
436 char fLTypeName = 12;
437 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
441struct RTFStreamerElementSize {
442 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSize) -
sizeof(RUInt32BE))};
443 RUInt16BE fVersion{4};
445 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 7)};
446 RUInt16BE fVersionNamed{1};
447 RTFObject fObjectNamed{0x02000000 | 0x01000000};
449 char fName[5]{
'f',
'S',
'i',
'z',
'e' };
454 RUInt32BE fArrLength{0};
455 RUInt32BE fArrDim{0};
456 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
457 char fLTypeName = 12;
458 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
462struct RTFStreamerElementSeekHeader {
463 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekHeader) -
sizeof(RUInt32BE))};
464 RUInt16BE fVersion{4};
466 RUInt32BE fByteCountNamed{0x40000000 |
467 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
468 RUInt16BE fVersionNamed{1};
469 RTFObject fObjectNamed{0x02000000 | 0x01000000};
471 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'H',
'e',
'a',
'd',
'e',
'r' };
476 RUInt32BE fArrLength{0};
477 RUInt32BE fArrDim{0};
478 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
479 char fLTypeName = 13;
480 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
484struct RTFStreamerElementNBytesHeader {
485 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesHeader) -
sizeof(RUInt32BE))};
486 RUInt16BE fVersion{4};
488 RUInt32BE fByteCountNamed{0x40000000 |
489 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
490 RUInt16BE fVersionNamed{1};
491 RTFObject fObjectNamed{0x02000000 | 0x01000000};
493 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'H',
'e',
'a',
'd',
'e',
'r' };
498 RUInt32BE fArrLength{0};
499 RUInt32BE fArrDim{0};
500 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
501 char fLTypeName = 12;
502 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
506struct RTFStreamerElementLenHeader {
507 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenHeader) -
sizeof(RUInt32BE))};
508 RUInt16BE fVersion{4};
510 RUInt32BE fByteCountNamed{0x40000000 |
511 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
512 RUInt16BE fVersionNamed{1};
513 RTFObject fObjectNamed{0x02000000 | 0x01000000};
515 char fName[10]{
'f',
'L',
'e',
'n',
'H',
'e',
'a',
'd',
'e',
'r' };
520 RUInt32BE fArrLength{0};
521 RUInt32BE fArrDim{0};
522 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
523 char fLTypeName = 12;
524 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
528struct RTFStreamerElementSeekFooter {
529 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementSeekFooter) -
sizeof(RUInt32BE))};
530 RUInt16BE fVersion{4};
532 RUInt32BE fByteCountNamed{0x40000000 |
533 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 13)};
534 RUInt16BE fVersionNamed{1};
535 RTFObject fObjectNamed{0x02000000 | 0x01000000};
537 char fName[11]{
'f',
'S',
'e',
'e',
'k',
'F',
'o',
'o',
't',
'e',
'r' };
542 RUInt32BE fArrLength{0};
543 RUInt32BE fArrDim{0};
544 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
545 char fLTypeName = 13;
546 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
550struct RTFStreamerElementNBytesFooter {
551 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementNBytesFooter) -
sizeof(RUInt32BE))};
552 RUInt16BE fVersion{4};
554 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 15)};
555 RUInt16BE fVersionNamed{1};
556 RTFObject fObjectNamed{0x02000000 | 0x01000000};
558 char fName[13]{
'f',
'N',
'B',
'y',
't',
'e',
's',
'F',
'o',
'o',
't',
'e',
'r' };
563 RUInt32BE fArrLength{0};
564 RUInt32BE fArrDim{0};
565 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
566 char fLTypeName = 12;
567 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
571struct RTFStreamerElementLenFooter {
572 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementLenFooter) -
sizeof(RUInt32BE))};
573 RUInt16BE fVersion{4};
575 RUInt32BE fByteCountNamed{0x40000000 | (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 12)};
576 RUInt16BE fVersionNamed{1};
577 RTFObject fObjectNamed{0x02000000 | 0x01000000};
579 char fName[10]{
'f',
'L',
'e',
'n',
'F',
'o',
'o',
't',
'e',
'r' };
584 RUInt32BE fArrLength{0};
585 RUInt32BE fArrDim{0};
586 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
587 char fLTypeName = 12;
588 char fTypeName[12]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'i',
'n',
't' };
592struct RTFStreamerElementReserved {
593 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerElementReserved) -
sizeof(RUInt32BE))};
594 RUInt16BE fVersion{4};
596 RUInt32BE fByteCountNamed{0x40000000 |
597 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 11)};
598 RUInt16BE fVersionNamed{1};
599 RTFObject fObjectNamed{0x02000000 | 0x01000000};
601 char fName[9]{
'f',
'R',
'e',
's',
'e',
'r',
'v',
'e',
'd' };
606 RUInt32BE fArrLength{0};
607 RUInt32BE fArrDim{0};
608 char fMaxIndex[20]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
609 char fLTypeName = 13;
610 char fTypeName[13]{
'u',
'n',
's',
'i',
'g',
'n',
'e',
'd',
' ',
'l',
'o',
'n',
'g' };
614struct RTFStreamerVersion {
615 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerVersion) -
sizeof(RUInt32BE))};
616 RUInt32BE fNewClassTag{0xffffffff};
617 char fClassName[19]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'B',
'a',
's',
'i',
'c',
'T',
'y',
'p',
'e',
'\0'};
618 RUInt32BE fByteCountRemaining{0x40000000 |
619 (
sizeof(RTFStreamerVersion) - 2 *
sizeof(RUInt32BE) - 19 -
sizeof(RUInt32BE))};
620 RUInt16BE fVersion{2};
621 RTFStreamerElementVersion fStreamerElementVersion;
625struct RTFStreamerSize {
626 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSize) -
sizeof(RUInt32BE))};
627 RUInt32BE fClassTag{0x80000000};
628 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSize) - 3 *
sizeof(RUInt32BE))};
629 RUInt16BE fVersion{2};
630 RTFStreamerElementSize fStreamerElementSize;
634struct RTFStreamerSeekHeader {
635 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekHeader) -
sizeof(RUInt32BE))};
636 RUInt32BE fClassTag{0x80000000};
637 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekHeader) - 3 *
sizeof(RUInt32BE))};
638 RUInt16BE fVersion{2};
639 RTFStreamerElementSeekHeader fStreamerElementSeekHeader;
643struct RTFStreamerNBytesHeader {
644 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) -
sizeof(RUInt32BE))};
645 RUInt32BE fClassTag{0x80000000};
646 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesHeader) - 3 *
sizeof(RUInt32BE))};
647 RUInt16BE fVersion{2};
648 RTFStreamerElementNBytesHeader fStreamerElementNBytesHeader;
652struct RTFStreamerLenHeader {
653 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenHeader) -
sizeof(RUInt32BE))};
654 RUInt32BE fClassTag{0x80000000};
655 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenHeader) - 3 *
sizeof(RUInt32BE))};
656 RUInt16BE fVersion{2};
657 RTFStreamerElementLenHeader fStreamerElementLenHeader;
661struct RTFStreamerSeekFooter {
662 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerSeekFooter) -
sizeof(RUInt32BE))};
663 RUInt32BE fClassTag{0x80000000};
664 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerSeekFooter) - 3 *
sizeof(RUInt32BE))};
665 RUInt16BE fVersion{2};
666 RTFStreamerElementSeekFooter fStreamerElementSeekFooter;
670struct RTFStreamerNBytesFooter {
671 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) -
sizeof(RUInt32BE))};
672 RUInt32BE fClassTag{0x80000000};
673 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerNBytesFooter) - 3 *
sizeof(RUInt32BE))};
674 RUInt16BE fVersion{2};
675 RTFStreamerElementNBytesFooter fStreamerElementNBytesFooter;
679struct RTFStreamerLenFooter {
680 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerLenFooter) -
sizeof(RUInt32BE))};
681 RUInt32BE fClassTag{0x80000000};
682 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerLenFooter) - 3 *
sizeof(RUInt32BE))};
683 RUInt16BE fVersion{2};
684 RTFStreamerElementLenFooter fStreamerElementLenFooter;
688struct RTFStreamerReserved {
689 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerReserved) -
sizeof(RUInt32BE))};
690 RUInt32BE fClassTag{0x80000000};
691 RUInt32BE fByteCountRemaining{0x40000000 | (
sizeof(RTFStreamerReserved) - 3 *
sizeof(RUInt32BE))};
692 RUInt16BE fVersion{2};
693 RTFStreamerElementReserved fStreamerElementReserved;
697struct RTFStreamerInfoObject {
698 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoObject) -
sizeof(fByteCount))};
699 RUInt32BE fNewClassTag{0xffffffff};
700 char fClassName[14]{
'T',
'S',
't',
'r',
'e',
'a',
'm',
'e',
'r',
'I',
'n',
'f',
'o',
'\0' };
701 RUInt32BE fByteCountRemaining{0x40000000 |
702 (
sizeof(RTFStreamerInfoObject) - 2 *
sizeof(RUInt32BE) - 14 -
sizeof(RUInt32BE))};
703 RUInt16BE fVersion{9};
705 RUInt32BE fByteCountNamed{0x40000000 |
706 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 29 )};
707 RUInt16BE fVersionNamed{1};
708 RTFObject fObjectNamed{0x02000000 | 0x01000000 | 0x00010000};
710 char fName[27]{
'R',
'O',
'O',
'T',
':',
':',
711 'E',
'x',
'p',
'e',
'r',
'i',
'm',
'e',
'n',
't',
'a',
'l',
':',
':',
712 'R',
'N',
'T',
'u',
'p',
'l',
'e'};
715 RInt32BE fChecksum{ChecksumRNTupleClass()};
716 RUInt32BE fVersionRNTuple{1};
718 RUInt32BE fByteCountObjArr{0x40000000 |
719 (
sizeof(RUInt32BE) + 10 +
sizeof(RUInt32BE) +
720 sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2*
sizeof(RUInt32BE) +
721 sizeof(fStreamers))};
722 RUInt32BE fNewClassTagObjArray{0xffffffff};
723 char fClassNameObjArray[10]{
'T',
'O',
'b',
'j',
'A',
'r',
'r',
'a',
'y',
'\0'};
724 RUInt32BE fByteCountObjArrRemaining{0x40000000 |
725 (
sizeof(RUInt16BE) +
sizeof(RTFObject) + 1 + 2*
sizeof(RUInt32BE) +
726 sizeof(fStreamers))};
727 RUInt16BE fVersionObjArr{3};
728 RTFObject fObjectObjArr{0x02000000};
731 RUInt32BE fNObjects{9};
732 RUInt32BE fLowerBound{0};
735 RTFStreamerVersion fStreamerVersion;
736 RTFStreamerSize fStreamerSize;
737 RTFStreamerSeekHeader fStreamerSeekHeader;
738 RTFStreamerNBytesHeader fStreamerNBytesHeader;
739 RTFStreamerLenHeader fStreamerLenHeader;
740 RTFStreamerSeekFooter fStreamerSeekFooter;
741 RTFStreamerNBytesFooter fStreamerNBytesFooter;
742 RTFStreamerLenFooter fStreamerLenFooter;
743 RTFStreamerReserved fStreamerReserved;
748struct RTFStreamerInfoList {
749 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFStreamerInfoList) -
sizeof(fByteCount))};
750 RUInt16BE fVersion{5};
751 RTFObject fObject{0x02000000};
753 RUInt32BE fNObjects{1};
754 RTFStreamerInfoObject fStreamerInfo;
757 std::uint32_t GetSize()
const {
return sizeof(RTFStreamerInfoList); }
763 std::uint32_t GetSize()
const {
return sizeof(RTFKeyList); }
764 explicit RTFKeyList(std::uint32_t nKeys) : fNKeys(nKeys) {}
773 RUInt32BE fNBytesKeys{0};
774 RUInt32BE fNBytesName{0};
778 RUInt32BE fSeekDir{100};
779 RUInt32BE fSeekParent{0};
780 RUInt32BE fSeekKeys{0};
783 RUInt64BE fSeekDir{100};
784 RUInt64BE fSeekParent{0};
785 RUInt64BE fSeekKeys{0};
789 RTFFile() : fInfoShort() {}
791 std::uint32_t GetSize(std::uint32_t versionKey = 0)
const {
792 if (versionKey >= 1000)
793 return 18 +
sizeof(fInfoLong);
794 return 18 +
sizeof(fInfoShort);
797 std::uint64_t GetSeekKeys(std::uint32_t versionKey = 0)
const {
798 if (versionKey >= 1000)
799 return fInfoLong.fSeekKeys;
800 return fInfoShort.fSeekKeys;
806 RUInt32BE fByteCount{0x40000000 | (
sizeof(RTFNTuple) -
sizeof(fByteCount))};
807 RUInt16BE fVersionClass{0};
808 RInt32BE fChecksum{ChecksumRNTupleClass()};
809 RUInt32BE fVersionInternal{0};
811 RUInt64BE fSeekHeader{0};
812 RUInt32BE fNBytesHeader{0};
813 RUInt32BE fLenHeader{0};
814 RUInt64BE fSeekFooter{0};
815 RUInt32BE fNBytesFooter{0};
816 RUInt32BE fLenFooter{0};
817 RUInt64BE fReserved{0};
819 RTFNTuple() =
default;
821 fVersionInternal = inMemoryNTuple.
fVersion;
831 std::uint32_t GetSize()
const {
return sizeof(RTFNTuple); }
848struct RBareFileHeader {
849 char fMagic[7]{
'r',
'n',
't',
'u',
'p',
'l',
'e' };
853 RUInt32BE fFormatVersion{1};
854 RUInt32BE fCompress{0};
861static constexpr char const *kBlobClassName =
"RBlob";
863static constexpr char const *kNTupleClassName =
"ROOT::Experimental::RNTuple";
867class RKeyBlob :
public TKey {
870 fClassName = kBlobClassName;
871 fKeylen += strlen(kBlobClassName);
875 void Reserve(
size_t nbytes, std::uint64_t *seekKey)
886namespace Experimental {
890struct RTFileControlBlock {
892 std::uint32_t fSeekNTuple{0};
908 if (std::string(ident, 4) ==
"root")
909 return GetNTupleProper(ntupleName);
911 return GetNTupleBare(ntupleName);
917 RTFHeader fileHeader;
918 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
922 ReadBuffer(&key,
sizeof(key), fileHeader.fBEGIN);
923 auto offset = fileHeader.fBEGIN + key.fKeyLen;
925 offset +=
name.GetSize();
927 offset +=
name.GetSize();
932 offset =
file.GetSeekKeys(key.fVersion);
934 offset += key.fKeyLen;
936 offset +=
sizeof(nKeys);
938 for (
unsigned int i = 0; i < nKeys; ++i) {
940 auto offsetNextKey = offset + key.fKeyLen;
942 offset += key.GetHeaderSize();
944 offset +=
name.GetSize();
951 offset = offsetNextKey;
955 ReadBuffer(&key,
sizeof(key), key.GetSeekKey());
956 offset = key.GetSeekKey() + key.fKeyLen;
959 return ntuple.ToRNTuple();
964 RBareFileHeader fileHeader;
965 ReadBuffer(&fileHeader,
sizeof(fileHeader), 0);
967 auto offset =
sizeof(fileHeader);
971 offset +=
name.GetSize();
975 return ntuple.ToRNTuple();
981 auto nread = fRawFile->ReadAt(buffer, nbytes, offset);
997 const void *buffer,
size_t nbytes, std::int64_t offset)
1001 if ((offset >= 0) && (
static_cast<std::uint64_t
>(offset) != fFilePos)) {
1002 retval = fseek(fFile, offset, SEEK_SET);
1006 retval = fwrite(buffer, 1, nbytes, fFile);
1013 const void *buffer, std::size_t nbytes, std::size_t len, std::int64_t offset,
1014 std::uint64_t directoryOffset,
1015 const std::string &className,
1016 const std::string &objectName,
1017 const std::string &title)
1021 RTFString strClass{className};
1022 RTFString strObject{objectName};
1023 RTFString strTitle{title};
1025 RTFKey key(offset, directoryOffset, strClass, strObject, strTitle, len, nbytes);
1026 Write(&key, key.fKeyHeaderSize, offset);
1027 Write(&strClass, strClass.GetSize());
1028 Write(&strObject, strObject.GetSize());
1029 Write(&strTitle, strTitle.GetSize());
1030 auto offsetData = fFilePos;
1032 Write(buffer, nbytes);
1042 const void *buffer,
size_t nbytes, std::int64_t offset)
1045 fFile->Seek(offset);
1046 bool rv = fFile->WriteBuffer((
char *)(buffer), nbytes);
1052 const void *buffer,
size_t nbytes,
size_t len)
1054 std::uint64_t offsetKey;
1055 RKeyBlob keyBlob(fFile);
1056 keyBlob.Reserve(nbytes, &offsetKey);
1058 auto offset = offsetKey;
1059 RTFString strClass{kBlobClassName};
1060 RTFString strObject;
1062 RTFKey keyHeader(offset, offset, strClass, strObject, strTitle, len, nbytes);
1064 Write(&keyHeader, keyHeader.fKeyHeaderSize, offset);
1065 offset += keyHeader.fKeyHeaderSize;
1066 Write(&strClass, strClass.GetSize(), offset);
1067 offset += strClass.GetSize();
1068 Write(&strObject, strObject.GetSize(), offset);
1069 offset += strObject.GetSize();
1070 Write(&strTitle, strTitle.GetSize(), offset);
1071 offset += strTitle.GetSize();
1072 auto offsetData = offset;
1073 Write(buffer, nbytes, offset);
1097 std::string fileName(path);
1098 size_t idxDirSep = fileName.find_last_of(
"\\/");
1099 if (idxDirSep != std::string::npos) {
1100 fileName.erase(0, idxDirSep + 1);
1102 FILE *fileStream = fopen(std::string(path.data(), path.size()).c_str(),
"wb");
1106 writer->fFileSimple.fFile = fileStream;
1107 writer->fFileName = fileName;
1109 switch (containerFormat) {
1111 writer->WriteTFileSkeleton(defaultCompression);
1115 writer->WriteBareFileSkeleton(defaultCompression);
1118 R__ASSERT(
false &&
"Internal error: unhandled container format");
1128 file = std::unique_ptr<TFile>(
TFile::Open(std::string(path.data(), path.size()).c_str(),
"RECREATE"));
1150 fFileProper.fFile->WriteObject(&fNTupleAnchor, fNTupleName.c_str());
1151 fFileProper.fFile->Write();
1157 RTFNTuple ntupleOnDisk(fNTupleAnchor);
1160 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize(), fFileSimple.fControlBlock->fSeekNTuple);
1161 fflush(fFileSimple.fFile);
1165 fFileSimple.fControlBlock->fHeader.SetSeekFree(fFileSimple.fFilePos);
1167 RTFFreeEntry freeEntry;
1168 RTFKey keyFreeList(fFileSimple.fControlBlock->fHeader.GetSeekFree(), 100,
1169 strEmpty, strEmpty, strEmpty, freeEntry.GetSize());
1170 std::uint64_t firstFree = fFileSimple.fControlBlock->fHeader.GetSeekFree() + keyFreeList.GetSize();
1171 freeEntry.Set(firstFree, std::max(2000000000ULL, ((firstFree / 1000000000ULL) + 1) * 1000000000ULL));
1172 fFileSimple.WriteKey(
1173 &freeEntry, freeEntry.GetSize(), freeEntry.GetSize(), fFileSimple.fControlBlock->fHeader.GetSeekFree(),
1175 fFileSimple.fControlBlock->fHeader.SetNbytesFree(fFileSimple.fFilePos -
1176 fFileSimple.fControlBlock->fHeader.GetSeekFree());
1177 fFileSimple.fControlBlock->fHeader.SetEnd(fFileSimple.fFilePos);
1179 auto szNTuple = ntupleOnDisk.GetSize();
1180 fFileSimple.WriteKey(&ntupleOnDisk, szNTuple, szNTuple, fFileSimple.fControlBlock->fSeekNTuple, 100,
1181 kNTupleClassName, fNTupleName);
1183 fFileSimple.Write(&fFileSimple.fControlBlock->fHeader, fFileSimple.fControlBlock->fHeader.GetSize(), 0);
1184 fflush(fFileSimple.fFile);
1190 std::uint64_t offset;
1193 offset = fFileSimple.fFilePos;
1194 fFileSimple.Write(data, nbytes);
1196 offset = fFileSimple.WriteKey(data, nbytes, len, -1, 100, kBlobClassName);
1199 offset = fFileProper.WriteKey(data, nbytes, len);
1206 const void *data,
size_t nbytes,
size_t lenHeader)
1208 auto offset = WriteBlob(data, nbytes, lenHeader);
1209 fNTupleAnchor.fLenHeader = lenHeader;
1210 fNTupleAnchor.fNBytesHeader = nbytes;
1211 fNTupleAnchor.fSeekHeader = offset;
1217 const void *data,
size_t nbytes,
size_t lenFooter)
1219 auto offset = WriteBlob(data, nbytes, lenFooter);
1220 fNTupleAnchor.fLenFooter = lenFooter;
1221 fNTupleAnchor.fNBytesFooter = nbytes;
1222 fNTupleAnchor.fSeekFooter = offset;
1229 RBareFileHeader bareHeader;
1230 bareHeader.fCompress = defaultCompression;
1231 fFileSimple.Write(&bareHeader,
sizeof(bareHeader), 0);
1232 RTFString ntupleName{fNTupleName};
1233 fFileSimple.Write(&ntupleName, ntupleName.GetSize());
1236 RTFNTuple ntupleOnDisk;
1237 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fFilePos;
1238 fFileSimple.Write(&ntupleOnDisk, ntupleOnDisk.GetSize());
1244 RTFString strTFile{
"TFile"};
1245 RTFString strFileName{fFileName};
1246 RTFString strTList{
"TList"};
1247 RTFString strStreamerInfo{
"StreamerInfo"};
1248 RTFString strStreamerTitle{
"Doubly linked list"};
1249 RTFString strRNTupleClass{
"ROOT::Experimental::RNTuple"};
1250 RTFString strRNTupleName{fNTupleName};
1253 fFileSimple.fControlBlock->fHeader = RTFHeader(defaultCompression);
1257 RTFKey keyRoot(100, 0, strTFile, strFileName, strEmpty,
1258 fileRoot.GetSize() + strFileName.GetSize() + strEmpty.GetSize());
1259 std::uint32_t nbytesName = keyRoot.fKeyLen + strFileName.GetSize() + 1;
1260 fileRoot.fNBytesName = nbytesName;
1261 fFileSimple.fControlBlock->fHeader.SetNbytesName(nbytesName);
1266 fFileSimple.fControlBlock->fHeader.SetSeekInfo(100 + keyRoot.GetSize());
1267 RTFKey keyStreamerInfo(
1268 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100, strTList, strStreamerInfo, strStreamerTitle, 0);
1269 RTFStreamerInfoList streamerInfo;
1270 auto classTagOffset = keyStreamerInfo.fKeyLen +
1271 offsetof(
struct RTFStreamerInfoList, fStreamerInfo) +
1272 offsetof(
struct RTFStreamerInfoObject, fStreamers) +
1273 offsetof(
struct RTFStreamerVersion, fNewClassTag) + 2;
1274 streamerInfo.fStreamerInfo.fStreamers.fStreamerSize.fClassTag = 0x80000000 | classTagOffset;
1275 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekHeader.fClassTag = 0x80000000 | classTagOffset;
1276 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesHeader.fClassTag = 0x80000000 | classTagOffset;
1277 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenHeader.fClassTag = 0x80000000 | classTagOffset;
1278 streamerInfo.fStreamerInfo.fStreamers.fStreamerSeekFooter.fClassTag = 0x80000000 | classTagOffset;
1279 streamerInfo.fStreamerInfo.fStreamers.fStreamerNBytesFooter.fClassTag = 0x80000000 | classTagOffset;
1280 streamerInfo.fStreamerInfo.fStreamers.fStreamerLenFooter.fClassTag = 0x80000000 | classTagOffset;
1281 streamerInfo.fStreamerInfo.fStreamers.fStreamerReserved.fClassTag = 0x80000000 | classTagOffset;
1283 auto szStreamerInfo = compressor(&streamerInfo, streamerInfo.GetSize(), 1);
1284 fFileSimple.WriteKey(compressor.
GetZipBuffer(), szStreamerInfo, streamerInfo.GetSize(),
1285 fFileSimple.fControlBlock->fHeader.GetSeekInfo(), 100,
1286 "TList",
"StreamerInfo",
"Doubly linked list");
1287 fFileSimple.fControlBlock->fHeader.SetNbytesInfo(
1288 fFileSimple.fFilePos - fFileSimple.fControlBlock->fHeader.GetSeekInfo());
1291 RTFNTuple ntupleOnDisk;
1292 fFileSimple.fControlBlock->fSeekNTuple = fFileSimple.fFilePos;
1293 RTFKey keyRNTuple(fFileSimple.fControlBlock->fSeekNTuple, 100, strRNTupleClass, strRNTupleName, strEmpty,
1294 ntupleOnDisk.GetSize());
1295 fFileSimple.WriteKey(&ntupleOnDisk, ntupleOnDisk.GetSize(), ntupleOnDisk.GetSize(),
1296 fFileSimple.fControlBlock->fSeekNTuple, 100,
"ROOT::Experimental::RNTUple", fNTupleName,
"");
1299 fileRoot.fInfoShort.fSeekKeys = fFileSimple.fFilePos;
1300 RTFKeyList keyList{1};
1301 RTFKey keyKeyList(fileRoot.GetSeekKeys(), 100, strEmpty, strEmpty, strEmpty, keyList.GetSize() + keyRNTuple.fKeyLen);
1302 fFileSimple.Write(&keyKeyList, keyKeyList.fKeyHeaderSize, fileRoot.GetSeekKeys());
1303 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1304 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1305 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1306 fFileSimple.Write(&keyList, keyList.GetSize());
1307 fFileSimple.Write(&keyRNTuple, keyRNTuple.fKeyHeaderSize);
1308 fFileSimple.Write(&strRNTupleClass, strRNTupleClass.GetSize());
1309 fFileSimple.Write(&strRNTupleName, strRNTupleName.GetSize());
1310 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1311 fileRoot.fNBytesKeys = fFileSimple.fFilePos - fileRoot.GetSeekKeys();
1313 auto tail = fFileSimple.fFilePos;
1314 fFileSimple.Write(&keyRoot, keyRoot.fKeyHeaderSize, 100);
1315 fFileSimple.Write(&strTFile, strTFile.GetSize());
1316 fFileSimple.Write(&strFileName, strFileName.GetSize());
1317 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1318 fFileSimple.Write(&strFileName, strFileName.GetSize());
1319 fFileSimple.Write(&strEmpty, strEmpty.GetSize());
1320 fFileSimple.Write(&fileRoot, fileRoot.GetSize());
1321 fFileSimple.fFilePos = tail;
1322 auto retval = fseek(fFileSimple.fFile, tail, SEEK_SET);
1324 fFileSimple.fFilePos = tail;
#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.
const void * GetZipBuffer()
RNTuple GetNTupleProper(std::string_view ntupleName)
Used when the file turns out to be a TFile container.
RMiniFileReader()=default
RNTuple GetNTuple(std::string_view ntupleName)
Extracts header and footer location for the RNTuple identified by ntupleName.
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 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.
basic_string_view< char > string_view
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 ...
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.