Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleZip.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleZip.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2019-11-21
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_RNTupleZip
14#define ROOT_RNTupleZip
15
16#include <RZip.h>
17#include <TError.h>
18
19#include <ROOT/RError.hxx>
20
21#include <algorithm>
22#include <array>
23#include <cstring>
24#include <functional>
25#include <memory>
26#include <utility>
27
28namespace ROOT {
29namespace Internal {
30
31// clang-format off
32/**
33\class ROOT::Internal::RNTupleCompressor
34\ingroup NTuple
35\brief Helper class to compress data blocks in the ROOT compression frame format
36*/
37// clang-format on
39public:
41 RNTupleCompressor(const RNTupleCompressor &other) = delete;
45
46 /// Returns the size of the compressed data, written into the provided output buffer.
47 static std::size_t Zip(const void *from, std::size_t nbytes, int compression, void *to)
48 {
49 R__ASSERT(from != nullptr);
50 R__ASSERT(to != nullptr);
51 auto cxLevel = compression % 100;
52 if (cxLevel == 0 || nbytes == 0) {
53 memcpy(to, from, nbytes);
54 return nbytes;
55 }
56
57 auto cxAlgorithm = static_cast<ROOT::RCompressionSetting::EAlgorithm::EValues>(compression / 100);
58 const auto blocks = ROOT::Internal::GetZipBlocks(nbytes);
59 const unsigned int nZipBlocks = blocks.fNBlocks;
60 const int szBlock = blocks.fBlockSize;
61 const char *source = static_cast<const char *>(from);
62 int szTarget = nbytes;
63 char *target = reinterpret_cast<char *>(to);
64 int szOutBlock = 0;
65 int szRemaining = nbytes;
66 size_t szZipData = 0;
67 for (unsigned int i = 0; i < nZipBlocks; ++i) {
68 int szSource = std::min(szBlock, szRemaining);
69 R__zipMultipleAlgorithm(cxLevel, &szSource, source, &szTarget, target, &szOutBlock, cxAlgorithm);
70 R__ASSERT(szOutBlock >= 0);
71 if ((szOutBlock == 0) || (szOutBlock >= szSource)) {
72 // Uncompressible block, we have to store the entire input data stream uncompressed
73 memcpy(to, from, nbytes);
74 return nbytes;
75 }
76
77 szZipData += szOutBlock;
78 source += szSource;
79 target += szOutBlock;
80 szRemaining -= szSource;
81 }
82 R__ASSERT(szRemaining == 0);
83 R__ASSERT(szZipData < nbytes);
84 return szZipData;
85 }
86};
87
88// clang-format off
89/**
90\class ROOT::Internal::RNTupleDecompressor
91\ingroup NTuple
92\brief Helper class to uncompress data blocks in the ROOT compression frame format
93*/
94// clang-format on
96public:
102
103 /**
104 * The nbytes parameter provides the size ls of the from buffer. The dataLen gives the size of the uncompressed data.
105 * The block is uncompressed iff nbytes == dataLen.
106 */
107 static void Unzip(const void *from, size_t nbytes, size_t dataLen, void *to)
108 {
109 if (dataLen == nbytes) {
110 memcpy(to, from, nbytes);
111 return;
112 }
113 R__ASSERT(dataLen > nbytes);
114
115 const unsigned char *source = static_cast<const unsigned char *>(from);
116 unsigned char *target = static_cast<unsigned char *>(to);
117 size_t szRemainingLen = dataLen;
118 size_t szRemainingNbytes = nbytes;
119 do {
120 if (R__unlikely(szRemainingNbytes < ROOT::Internal::kZipHeaderSize)) {
121 throw ROOT::RException(R__FAIL("zip buffer too short"));
122 }
123 int szSource;
124 int szTarget;
125 int retval = R__unzip_header(&szSource, source, &szTarget);
126 if (R__unlikely(!((retval == 0) && (szSource > 0) && (szTarget > szSource) &&
127 (static_cast<unsigned int>(szSource) <= szRemainingNbytes) &&
128 (static_cast<unsigned int>(szTarget) <= szRemainingLen)))) {
129 throw ROOT::RException(R__FAIL("failed to unzip buffer header"));
130 }
131
132 int unzipBytes = 0;
133 R__unzip(&szSource, source, &szTarget, target, &unzipBytes);
134 if (R__unlikely(unzipBytes != szTarget)) {
135 throw ROOT::RException(R__FAIL(std::string("unexpected length after unzipping the buffer (wanted: ") +
136 std::to_string(szTarget) + ", got: " + std::to_string(unzipBytes) + ")"));
137 }
138
139 target += szTarget;
140 source += szSource;
141 szRemainingNbytes -= szSource;
142 szRemainingLen -= unzipBytes;
143 } while (szRemainingLen > 0);
144 R__ASSERT(szRemainingLen == 0);
145 if (szRemainingNbytes > 0) {
146 throw ROOT::RException(R__FAIL(std::string("unexpected trailing bytes in zip buffer")));
147 }
148 }
149};
150
151} // namespace Internal
152} // namespace ROOT
153
154#endif
#define R__unlikely(expr)
Definition RConfig.hxx:568
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:322
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:139
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 target
Helper class to compress data blocks in the ROOT compression frame format.
RNTupleCompressor & operator=(const RNTupleCompressor &other)=delete
static std::size_t Zip(const void *from, std::size_t nbytes, int compression, void *to)
Returns the size of the compressed data, written into the provided output buffer.
RNTupleCompressor(RNTupleCompressor &&other)=delete
RNTupleCompressor(const RNTupleCompressor &other)=delete
RNTupleCompressor & operator=(RNTupleCompressor &&other)=delete
Helper class to uncompress data blocks in the ROOT compression frame format.
RNTupleDecompressor(RNTupleDecompressor &&other)=delete
static void Unzip(const void *from, size_t nbytes, size_t dataLen, void *to)
The nbytes parameter provides the size ls of the from buffer.
RNTupleDecompressor(const RNTupleDecompressor &other)=delete
RNTupleDecompressor & operator=(const RNTupleDecompressor &other)=delete
RNTupleDecompressor & operator=(RNTupleDecompressor &&other)=delete
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
EValues
Note: this is only temporarily a struct and will become a enum class hence the name convention used.
Definition Compression.h:88