BmnRoot
26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Toggle main menu visibility
Loading...
Searching...
No Matches
BmnFileReaderZLib.cxx
Go to the documentation of this file.
1
// headers from this target
2
#include "BmnFileReaderZLib.h"
3
4
#include "BmnDefinitions.h"
5
// std:: headers
6
#include <cassert>
7
#include <filesystem>
8
// the main ZLib header
9
#ifdef BMNCOMPRESSION_WITH_ZLIB
10
#include <zlib.h>
11
#else
12
// If we build without the library, it would be find to use #pragma on the entire object, without push
13
// and pop, but it's nothing too important for us here - just for simplicity I'm going with this def
14
DISABLE_UNUSED_PARAM_WARNING
15
#endif
// BMNCOMPRESSION_WITH_ZLIB
16
17
// o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o
18
// ================== BmnFileReaderZLib public methods ==================
19
// o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o
20
21
// ========== BmnIFileReaderInterface ==========
22
23
BmnFileReaderZLib::BmnFileReaderZLib
(
const
std::string& fileName)
24
:
BmnIFileReader
(
BmnFileType
::
ZLib
, fileName)
25
,
fZlibStream
(nullptr)
26
,
fArchiveReadManager
(*this)
27
,
fNumberOfReadBytes
(0ull)
28
,
fLastReturnStatus
(0)
29
{}
30
31
BmnFileReaderZLib::BmnFileReaderZLib
(std::string&& fileName)
32
:
BmnIFileReader
(
BmnFileType
::
ZLib
,
std
::move(fileName))
33
,
fZlibStream
(nullptr)
34
,
fArchiveReadManager
(*this)
35
,
fNumberOfReadBytes
(0ull)
36
,
fLastReturnStatus
(0)
37
{}
38
39
BmnFileReaderZLib::BmnFileReaderZLib
(
const
std::filesystem::path& filePath)
40
:
BmnIFileReader
(
BmnFileType
::
ZLib
, filePath)
41
,
fZlibStream
(nullptr)
42
,
fArchiveReadManager
(*this)
43
,
fNumberOfReadBytes
(0ull)
44
,
fLastReturnStatus
(0)
45
{}
46
47
BmnFileReaderZLib::BmnFileReaderZLib
(std::filesystem::path&& filePath)
48
:
BmnIFileReader
(
BmnFileType
::
ZLib
,
std
::move(filePath))
49
,
fZlibStream
(nullptr)
50
,
fArchiveReadManager
(*this)
51
,
fNumberOfReadBytes
(0ull)
52
,
fLastReturnStatus
(0)
53
{}
54
55
BmnFileReaderZLib::~BmnFileReaderZLib
()
56
{
57
BmnFileReaderZLib::Close
();
58
// another delete here as Close might go bad and still not break the code (in Release builds)
59
#ifdef BMNCOMPRESSION_WITH_ZLIB
60
delete
fZlibStream
;
61
#endif
// BMNCOMPRESSION_WITH_ZLIB
62
}
63
64
void
BmnFileReaderZLib::Open
(
const
BmnBinaryFileProcessingOptions
processingFlags)
65
{
66
#ifdef BMNCOMPRESSION_WITH_ZLIB
67
/*
68
While we actually don't need so many comments and checks here, we are still performing them just to ensure
69
one doesn't make an accidental mistake - it might be easier to catch it
70
*/
71
if
(
fZlibStream
) {
72
LOG(error) <<
"ZLib stream is already valid!"
;
73
return
;
74
}
75
if
(!
PerformStandardChecksBeforeOpening
(processingFlags))
76
return
;
77
fArchiveReadManager
.Open(
fFilePath
, std::ios::in | std::ios::binary);
78
fZlibStream
=
79
new
z_stream_s{
nullptr
, 0u, 0u,
nullptr
, 0u, 0u,
nullptr
,
nullptr
,
nullptr
,
nullptr
,
nullptr
, 0, 0u, 0u};
80
// according to documentation, adding +32 enables auto-detection of headers, i.e., the stream will decide whether to
81
// use gzip or zlib formats
82
if
(inflateInit2(
fZlibStream
, 15 + 32) != Z_OK) {
83
LOG(error) <<
"Failed to initialize ZLib stream! Reason: "
<<
fZlibStream
->msg <<
'\n'
;
84
inflateEnd(
fZlibStream
);
85
delete
fZlibStream
;
86
fZlibStream
=
nullptr
;
87
fArchiveReadManager
.Close();
88
}
89
90
#else
91
throw
std::runtime_error{
"Trying to use ZLIB while BMN is not compiled with it!"
};
92
#endif
// BMNCOMPRESSION_WITH_ZLIB
93
}
94
95
void
BmnFileReaderZLib::Close
() noexcept
96
{
97
#ifdef BMNCOMPRESSION_WITH_ZLIB
98
if
(!
fZlibStream
)
99
return
;
100
if
(inflateEnd(
fZlibStream
) != Z_OK) {
101
LOG(fatal) <<
"Failed to free ZLib stream - possible huge memory leak! Failure reason: "
<<
fZlibStream
->msg
102
<<
'\n'
;
103
std::terminate();
104
}
105
delete
fZlibStream
;
106
fZlibStream
=
nullptr
;
107
fArchiveReadManager
.Close();
108
fNumberOfReadBytes
= 0ull;
109
fLastReturnStatus
= 0;
110
#endif
// BMNCOMPRESSION_WITH_ZLIB
111
}
112
113
int64_t
BmnFileReaderZLib::Read
(
void
* dataToFill,
const
int64_t sizeToFill)
114
{
115
#ifdef BMNCOMPRESSION_WITH_ZLIB
116
if
(!
IsStreamInGoodState
())
117
return
0ll;
118
return
fArchiveReadManager
.Read(dataToFill, sizeToFill);
119
#else
120
throw
std::runtime_error{
"Trying to use ZLIB while BMN is not compiled with it!"
};
121
#endif
// BMNCOMPRESSION_WITH_ZLIB
122
}
123
124
int64_t
BmnFileReaderZLib::Tell
() const noexcept
125
{
126
return
fNumberOfReadBytes
+
fArchiveReadManager
.GetCurrentOutputBufferPosition()
127
-
fArchiveReadManager
.GetTotalOutputBufferFilledSize();
128
}
129
130
void
BmnFileReaderZLib::Seek
(int64_t value)
131
{
132
#ifdef BMNCOMPRESSION_WITH_ZLIB
133
if
(value < 0ll || (
size_t
)value ==
fNumberOfReadBytes
)
134
return
;
135
if
(!
IsStreamInGoodState
()) {
136
LOG(error) <<
"Before calling `BmnFileReaderZLib::Seek` ensure to clear bad flags!\n"
;
137
return
;
138
}
139
if
(!
fZlibStream
) {
140
LOG(error) <<
"Before calling `BmnFileReaderZLib::Seek` ensure to open the stream!\n"
;
141
return
;
142
}
143
if
(!
fArchiveReadManager
.IsOpen()) {
144
LOG(error) <<
"Reading file missing while calling `BmnFileReaderZLib::Seek`\n"
;
145
return
;
146
}
147
if
((
size_t
)value < (
fNumberOfReadBytes
-
fArchiveReadManager
.GetTotalOutputBufferFilledSize())) {
148
Close
();
149
Open
(
BmnBinaryFileProcessingOptions::ReadBinary
);
150
}
151
// in theory I could check IsOpen again for unexpected errors, but....
152
fArchiveReadManager
.MoveToDecompressingLocation(value);
153
#else
154
throw
std::runtime_error{
"Trying to use ZLIB while BMN is not compiled with it!"
};
155
#endif
// BMNCOMPRESSION_WITH_ZLIB
156
}
157
158
bool
BmnFileReaderZLib::IsGood
() const noexcept
159
{
160
#ifdef BMNCOMPRESSION_WITH_ZLIB
161
return
fZlibStream
&&
IsStreamInGoodState
() &&
fArchiveReadManager
.IsGood();
162
#else
163
return
false
;
164
#endif
// BMNCOMPRESSION_WITH_ZLIB
165
}
166
167
bool
BmnFileReaderZLib::IsEOF
() const noexcept
168
{
169
return
fArchiveReadManager
.IsEOF();
170
}
171
172
void
BmnFileReaderZLib::ClearStateFlags
()
173
{
174
// I don't like this method much
175
fLastReturnStatus
= 0;
176
fArchiveReadManager
.Clear();
177
}
178
179
bool
BmnFileReaderZLib::IsOpen
() const noexcept
180
{
181
return
fArchiveReadManager
.IsOpen() &&
fZlibStream
;
182
}
183
184
// ========== BmnIArchiveLib Interface ==========
185
186
BmnFileStreamResults
BmnFileReaderZLib::Uncompress
(
const
void
* source,
187
const
size_t
sourceTotalSize,
188
size_t
& numberOfReadBytes,
189
void
* output,
190
const
size_t
outputTotalSize,
191
size_t
& numberOfSetOutputBytes)
192
{
193
if
(!
fZlibStream
)
194
return
BmnFileStreamResults::FileNotOpen
;
195
#ifdef BMNCOMPRESSION_WITH_ZLIB
196
if
(!
IsStreamInGoodState
())
197
return
BmnFileStreamResults::TryingToReadBadStream
;
198
fZlibStream
->next_out = (Bytef*)output;
199
fZlibStream
->avail_out = (uInt)outputTotalSize;
200
fZlibStream
->total_out = 0u;
201
fZlibStream
->next_in = (Bytef*)source;
202
fZlibStream
->avail_in = (uInt)sourceTotalSize;
203
fZlibStream
->total_in = 0u;
204
fLastReturnStatus
= inflate(
fZlibStream
, Z_NO_FLUSH);
205
if
(!
IsStreamInGoodState
())
206
return
BmnFileStreamResults::UnexpectedFail
;
207
numberOfReadBytes = (size_t)
fZlibStream
->total_in;
208
numberOfSetOutputBytes = (size_t)
fZlibStream
->total_out;
209
fNumberOfReadBytes
+= numberOfSetOutputBytes;
210
if
(
fLastReturnStatus
== Z_STREAM_END)
211
return
BmnFileStreamResults::ReachedEOF
;
212
return
BmnFileStreamResults::Success
;
213
#else
214
throw
std::runtime_error{
"Trying to use ZLIB while BMN is not compiled with it!"
};
215
#endif
// BMNCOMPRESSION_WITH_ZLIB
216
}
217
218
std::string
BmnFileReaderZLib::GetLastUncompressErrorDescription
() const noexcept
219
{
220
#ifdef BMNCOMPRESSION_WITH_ZLIB
221
std::string strToReturn{};
222
if
(
fZlibStream
&&
fZlibStream
->msg)
223
strToReturn = std::string{
fZlibStream
->msg};
224
return
strToReturn;
225
#else
226
return
std::string{
"BMN NOT BUILT WITH ZLIB"
};
227
#endif
// BMNCOMPRESSION_WITH_ZLIB
228
}
229
230
bool
BmnFileReaderZLib::JumpsAllowed
() const noexcept
231
{
232
return
false
;
233
}
234
235
void
BmnFileReaderZLib::JumpTo
(
size_t
)
236
{
237
/*
238
In general with ZLib we could allow jumping while carefully building ZLib blocks. Still,
239
that would be allowed only in files written by our own encoder, while GZip would not produce
240
the same results. Thus, we don't allow jumps no matter what and if jumps are needed, we can
241
think about it and adapt later
242
*/
243
LOG(warning) <<
"Calling `BmnFileReaderZLib::JumpTo` while the type doesn't allow jumping!\n"
;
244
}
245
246
size_t
BmnFileReaderZLib::GetNumberOfDecompressedBytes
() const noexcept
247
{
248
return
fNumberOfReadBytes
;
249
}
250
251
bool
BmnFileReaderZLib::HasReachedTheEndOfStream
() const noexcept
252
{
253
#ifdef BMNCOMPRESSION_WITH_ZLIB
254
if
(!
IsStreamInGoodState
())
255
return
true
;
256
return
fLastReturnStatus
== Z_STREAM_END;
257
#else
258
return
true
;
259
#endif
// BMNCOMPRESSION_WITH_ZLIB
260
}
261
262
bool
BmnFileReaderZLib::IsStreamInGoodState
() const noexcept
263
{
264
#ifdef BMNCOMPRESSION_WITH_ZLIB
265
return
fLastReturnStatus
>= 0;
266
#else
267
return
false
;
268
#endif
// BMNCOMPRESSION_WITH_ZLIB
269
}
270
271
#ifndef BMNCOMPRESSION_WITH_ZLIB
272
RESTORE_UNUSED_PARAM_WARNING
273
#endif
// BMNCOMPRESSION_WITH_ZLIB
RESTORE_UNUSED_PARAM_WARNING
#define RESTORE_UNUSED_PARAM_WARNING
Definition
BmnDefinitions.h:23
DISABLE_UNUSED_PARAM_WARNING
#define DISABLE_UNUSED_PARAM_WARNING
Definition
BmnDefinitions.h:22
BmnFileReaderZLib::JumpsAllowed
virtual bool JumpsAllowed() const noexcept override
Definition
BmnFileReaderZLib.cxx:230
BmnFileReaderZLib::GetLastUncompressErrorDescription
virtual std::string GetLastUncompressErrorDescription() const noexcept override
Definition
BmnFileReaderZLib.cxx:218
BmnFileReaderZLib::~BmnFileReaderZLib
virtual ~BmnFileReaderZLib() override
Definition
BmnFileReaderZLib.cxx:55
BmnFileReaderZLib::JumpTo
virtual void JumpTo(size_t) override
Definition
BmnFileReaderZLib.cxx:235
BmnFileReaderZLib::GetNumberOfDecompressedBytes
virtual size_t GetNumberOfDecompressedBytes() const noexcept override
Definition
BmnFileReaderZLib.cxx:246
BmnFileReaderZLib::fNumberOfReadBytes
size_t fNumberOfReadBytes
Definition
BmnFileReaderZLib.h:206
BmnFileReaderZLib::Read
virtual int64_t Read(void *dataToFill, const int64_t sizeToFill) override
Definition
BmnFileReaderZLib.cxx:113
BmnFileReaderZLib::IsStreamInGoodState
virtual bool IsStreamInGoodState() const noexcept override
Definition
BmnFileReaderZLib.cxx:262
BmnFileReaderZLib::Tell
virtual int64_t Tell() const noexcept override
Definition
BmnFileReaderZLib.cxx:124
BmnFileReaderZLib::BmnFileReaderZLib
BmnFileReaderZLib(const std::string &fileName="")
Definition
BmnFileReaderZLib.cxx:23
BmnFileReaderZLib::IsGood
virtual bool IsGood() const noexcept override
Definition
BmnFileReaderZLib.cxx:158
BmnFileReaderZLib::IsEOF
virtual bool IsEOF() const noexcept override
Definition
BmnFileReaderZLib.cxx:167
BmnFileReaderZLib::Open
virtual void Open(const BmnBinaryFileProcessingOptions processingFlags=BmnBinaryFileProcessingOptions::ReadBinary) override
Definition
BmnFileReaderZLib.cxx:64
BmnFileReaderZLib::fZlibStream
z_stream_s * fZlibStream
Definition
BmnFileReaderZLib.h:204
BmnFileReaderZLib::IsOpen
virtual bool IsOpen() const noexcept override
Definition
BmnFileReaderZLib.cxx:179
BmnFileReaderZLib::Close
virtual void Close() noexcept override
Definition
BmnFileReaderZLib.cxx:95
BmnFileReaderZLib::Uncompress
virtual BmnFileStreamResults Uncompress(const void *source, const size_t sourceTotalSize, size_t &numberOfReadBytes, void *output, const size_t outputTotalSize, size_t &numberOfSetOutputBytes) override
Definition
BmnFileReaderZLib.cxx:186
BmnFileReaderZLib::fArchiveReadManager
BmnReaderCacheManager< 32ull *1024ull, 64ull *1024ull > fArchiveReadManager
Definition
BmnFileReaderZLib.h:205
BmnFileReaderZLib::HasReachedTheEndOfStream
virtual bool HasReachedTheEndOfStream() const noexcept override
Definition
BmnFileReaderZLib.cxx:251
BmnFileReaderZLib::Seek
virtual void Seek(int64_t value) override
Definition
BmnFileReaderZLib.cxx:130
BmnFileReaderZLib::fLastReturnStatus
int32_t fLastReturnStatus
Definition
BmnFileReaderZLib.h:207
BmnFileReaderZLib::ClearStateFlags
virtual void ClearStateFlags() override
Definition
BmnFileReaderZLib.cxx:172
BmnIFileReader::BmnIFileReader
BmnIFileReader(const BmnFileType fileType, const std::string &fileName="")
Definition
BmnIFileReader.cxx:8
BmnIFileReader::fFilePath
std::filesystem::path fFilePath
Definition
BmnIFileReader.h:199
BmnIFileReader::PerformStandardChecksBeforeOpening
bool PerformStandardChecksBeforeOpening(const BmnBinaryFileProcessingOptions processingFlags)
Definition
BmnIFileReader.cxx:72
BmnFileStreamResults
BmnFileStreamResults
Definition
BmnFileProcessingFlags.h:70
BmnFileStreamResults::Success
@ Success
Definition
BmnFileProcessingFlags.h:72
BmnFileStreamResults::ReachedEOF
@ ReachedEOF
Definition
BmnFileProcessingFlags.h:74
BmnFileStreamResults::FileNotOpen
@ FileNotOpen
Definition
BmnFileProcessingFlags.h:80
BmnFileStreamResults::UnexpectedFail
@ UnexpectedFail
Definition
BmnFileProcessingFlags.h:82
BmnFileStreamResults::TryingToReadBadStream
@ TryingToReadBadStream
Definition
BmnFileProcessingFlags.h:78
BmnFileType
BmnFileType
Definition
BmnFileProcessingFlags.h:16
BmnFileType::ZLib
@ ZLib
Definition
BmnFileProcessingFlags.h:20
BmnBinaryFileProcessingOptions
BmnBinaryFileProcessingOptions
Definition
BmnFileProcessingFlags.h:95
BmnBinaryFileProcessingOptions::ReadBinary
@ ReadBinary
Definition
BmnFileProcessingFlags.h:103
std
Definition
json.hpp:4446
compression
sources
BmnFileReaderZLib.cxx
Generated on
for BmnRoot by
1.17.0