BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnFileReaderZLibNG.h
Go to the documentation of this file.
1#pragma once
2#ifndef BmnFileReaderZLibNG_h
3#define BmnFileReaderZLibNG_h
4// headers from this target
6#include "BmnIFileReader.h"
8
9struct zng_stream_s;
10
11/*
12 * A class responsible for reading files compressed with ZLib-ng (Deflate algorithm, a.k.a. ZLib new generation)
13 * or GZip (internally, it uses ZLib which is also based on the Deflate algorithm). In our tests, we have observed
14 * that ZLib-ng achieves comparable compression ratios with ZLib (on higher compression level, while -1 is BAD)
15 * while compression/decompression is significantly faster. In fact, decompression can even be faster than ZStd
16 * compression! Thus, if ZLib-ng is built along with BMN, we will use this class by default for Deflate-compressed
17 * files, unless specified otherwise by a user.
18 * It's advisable to allocate this class on the heap as internally it uses big std::array
19 * @warning Using this class directly can result in throws if the ZLib-ng library is not found during compilation.
20 * Therefore, it's always advisable to obtain appropriate read objects through
21 * `BmnCompressionCreateNewSuitableReaderForAFile`
22 */
24 : public BmnIFileReader
25 , public BmnIArchiveLibRead
26{
27 public:
28 /*
29 * A standard constructor that sets a path to the input binary (Deflate-compressed) file
30 * @note The constructor will not check whether the file actually exists
31 * @param fileName A path (most likely relative) to the input binary (Deflate-compressed) file
32 * @warning If using relative paths, be very careful about currently-working directory as it might
33 * be something unexpected based on the directory that initalized an application
34 */
35 explicit BmnFileReaderZLibNG(const std::string& fileName = "");
36
37 /*
38 * A standard constructor that sets a path to the input binary (Deflate-compressed) file
39 * @note The constructor will not check whether the file actually exists
40 * @param fileName A path (most likely relative) to the input binary (Deflate-compressed) file
41 * @warning If using relative paths, be very careful about currently-working directory as it might
42 * be something unexpected based on the directory that initalized an application
43 */
44 explicit BmnFileReaderZLibNG(std::string&& fileName);
45
46 /*
47 * A standard constructor that sets a path to the input binary (Deflate-compressed) file
48 * @note The constructor will not check whether the file actually exists
49 * @param filePath A path to the input binary (Deflate-compressed) file
50 * @warning If using relative paths, be very careful about currently-working directory as it might
51 * be something unexpected based on the directory that initalized an application
52 */
53 explicit BmnFileReaderZLibNG(const std::filesystem::path& filePath);
54
55 /*
56 * A standard constructor that sets a path to the input binary (Deflate-compressed) file
57 * @note The constructor will not check whether the file actually exists
58 * @param filePath A path to the input binary (Deflate-compressed) file
59 * @warning If using relative paths, be very careful about currently-working directory as it might
60 * be something unexpected based on the directory that initalized an application
61 */
62 explicit BmnFileReaderZLibNG(std::filesystem::path&& filePath);
63
64 // Closes the stream while destroying the instance
65 virtual ~BmnFileReaderZLibNG() override;
69 BmnFileReaderZLibNG& operator=(BmnFileReaderZLibNG&&) noexcept = delete;
70
71 // ========== BmnIFileReaderInterface ==========
72
73 /*
74 * Opens a file for reading. The path of the file should be provided before calling this method
75 * @param processingFlags A flag that tells us how to open the file for reading. This class only supports
76 * `ReadBinary` flag
77 */
78 virtual void Open(
80
81 /*
82 * Closes the stream and resets all internal data. After calling `Close`, it's safe to reopen using the same
83 * instance of this class
84 */
85 virtual void Close() noexcept override;
86
87 /*
88 * Reads and decompresses the data while still managing caching for efficiency.
89 * @param dataToFill A buffer that will be filled with uncompressed data
90 * @param sizeToFill A number of bytes that will be filled in `dataToFill`
91 * @return A number of bytes that were filled in `dataToFill`. This value should almost always be the same as
92 * `sizeToFill` except when the end of the stream is reached (only if the user asked for more data than
93 * possible)
94 */
95 virtual int64_t Read(void* dataToFill, const int64_t sizeToFill) override;
96
97 /*
98 * A method that tells us what's the next byte to read
99 * @return A position of the next byte that should be read
100 */
101 [[nodiscard]] virtual int64_t Tell() const noexcept override;
102
103 /*
104 * A method that allows us to go to another place in the file (uncompressed data) and read from that place.
105 * This method is NOT EFFICIENT as it still needs to uncompress data to reach the needed place!
106 * @param value A position in uncompressed data to which one wants to move before the next read
107 */
108 virtual void Seek(int64_t value) override;
109
110 /*
111 * Check whether the reading stream is good
112 * @return 'true' if no decompression error has occurred and the input-file stream is good, or 'false' otherwise
113 */
114 [[nodiscard]] virtual bool IsGood() const noexcept override;
115
116 /*
117 * Check if we have reached the file. This will tell us if we have reached EOF in the uncompressed data, not
118 * in the file itself. That is, the file might be at EOF, while this method returns will return true as cache
119 * still has some data
120 * @return 'true' if both file and internal cache are completely read, 'false' otherwise
121 */
122 [[nodiscard]] virtual bool IsEOF() const noexcept override;
123
124 /*
125 * A method that clears bad flags after an error has occurred. Just calling this error will most likely
126 * not solve the problem, and you will get an error again in the next read. That is, before calling `Read`,
127 * remove the previous error source
128 */
129 virtual void ClearStateFlags() override;
130
131 /*
132 * @return 'true' if the input stream is open, or 'false' if not
133 */
134 [[nodiscard]] virtual bool IsOpen() const noexcept override;
135
136 // ========== BmnIArchiveLib Interface ==========
137
138 /*
139 * A method that is called to uncompress Deflate data with ZLib-ng
140 * @param source A pointer to a buffer with the subsequent compressed data that should be uncompressed
141 * @param sourceTotalSize A number of bytes available in the source buffer. If one has reached the EOF, it's ok to
142 * pass a 0 here
143 * @param numberOfReadBytes A number of bytes that were consumed by ZLib-ng while decompressing. This value will be
144 * set.
145 * @param output A pointer to a buffer that will be filled with uncompressed data
146 * @param outputTotalSize A number of bytes that may be filled in the output buffer
147 * @param numberOfSetOutputBytes A number of bytes that were set while decompressing. This value will be set.
148 * @return There are a few options:
149 * 1. `BmnFileStreamResults::FileNotOpen` if the stream is not open
150 * 2. `BmnFileStreamResults::TryingToReadBadStream` if the stream previously hit an error while it wasn't
151 * cleared later
152 * 3. `BmnFileStreamResults::UnexpectedFail` ZLib-ng failed while decompressing
153 * 4. `BmnFileStreamResults::ReachedEOF` ZLib-ng reached the end of frame (in our case file)
154 * 5. `BmnFileStreamResults::Success` ZLib-ng successfully uncompressed the package
155 */
156 virtual BmnFileStreamResults Uncompress(const void* source,
157 const size_t sourceTotalSize,
158 size_t& numberOfReadBytes,
159 void* output,
160 const size_t outputTotalSize,
161 size_t& numberOfSetOutputBytes) override;
162
163 /*
164 * If an error occurred while decompressing, this method can be called to obtain a description of the error
165 * @return A description of an error that occurred while decompressing, or an empty string if no such error happened
166 */
167 [[nodiscard]] virtual std::string GetLastUncompressErrorDescription() const noexcept override;
168
169 /*
170 * @return 'false' - this class doesn't allow jumping
171 */
172 [[nodiscard]] virtual bool JumpsAllowed() const noexcept override;
173
174 /*
175 * This method will do nothing but print an error. This class doesn't allow us to efficiently jump over the
176 * compressed file
177 */
178 virtual void JumpTo(size_t) override;
179
180 /*
181 * A method that tells us how many uncompressed bytes were read from an input file
182 * @return A number of uncompressed bytes that passed through the ZLib-ng
183 */
184 [[nodiscard]] virtual size_t GetNumberOfDecompressedBytes() const noexcept override;
185
186 /*
187 * A method that can be used to check if the reading stream has ended
188 * @return 'true' if we have reached EOF, 'false' otherwise
189 */
190 [[nodiscard]] virtual bool HasReachedTheEndOfStream() const noexcept override;
191
192 /*
193 * A method that checks whether the last read was good or not. If not, the stream is not good anymore
194 * @return 'true' if the stream is in a good state, 'false' otherwise
195 */
196 [[nodiscard]] virtual bool IsStreamInGoodState() const noexcept override;
197
198 // ========== BmnFileReaderZLibNG inlines ==========
199
200 [[nodiscard]] inline zng_stream_s* GetUnderlyingLibraryStream() const noexcept;
201 // Get number of read bytes via `GetNumberOfDecompressedBytes`
202 // No need to expose `fArchiveReadManager`
203
204 private:
205 zng_stream_s* fZlibNgStream;
206 BmnReaderCacheManager<32ull * 1024ull, 64ull * 1024ull> fArchiveReadManager;
207 size_t fNumberOfReadBytes;
208 int32_t fLastReturnStatus;
209 // 4 padding bytes
210};
211
212// 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 o
213// ================== BmnFileReaderZLibNG inline methods ==================
214// 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 o
215
216[[nodiscard]] inline zng_stream_s* BmnFileReaderZLibNG::GetUnderlyingLibraryStream() const noexcept
217{
218 return fZlibNgStream;
219}
220
221#endif // BmnFileReaderZLibNG_h
virtual int64_t Read(void *dataToFill, const int64_t sizeToFill) override
virtual bool IsStreamInGoodState() const noexcept override
zng_stream_s * GetUnderlyingLibraryStream() const noexcept
BmnFileReaderZLibNG(std::filesystem::path &&filePath)
virtual std::string GetLastUncompressErrorDescription() const noexcept override
virtual void Close() noexcept override
virtual void JumpTo(size_t) override
virtual void Open(const BmnBinaryFileProcessingOptions processingFlags=BmnBinaryFileProcessingOptions::ReadBinary) override
virtual bool IsGood() const noexcept override
virtual int64_t Tell() const noexcept override
BmnFileReaderZLibNG(const BmnFileReaderZLibNG &)=delete
BmnFileReaderZLibNG(const std::filesystem::path &filePath)
virtual bool HasReachedTheEndOfStream() const noexcept override
virtual ~BmnFileReaderZLibNG() override
virtual BmnFileStreamResults Uncompress(const void *source, const size_t sourceTotalSize, size_t &numberOfReadBytes, void *output, const size_t outputTotalSize, size_t &numberOfSetOutputBytes) override
virtual void ClearStateFlags() override
virtual bool IsOpen() const noexcept override
BmnReaderCacheManager< 32ull *1024ull, 64ull *1024ull > fArchiveReadManager
BmnFileReaderZLibNG(std::string &&fileName)
BmnFileReaderZLibNG(const std::string &fileName="")
BmnFileReaderZLibNG & operator=(const BmnFileReaderZLibNG &)=delete
virtual size_t GetNumberOfDecompressedBytes() const noexcept override
virtual bool JumpsAllowed() const noexcept override
BmnFileReaderZLibNG(BmnFileReaderZLibNG &&) noexcept=delete
virtual bool IsEOF() const noexcept override
virtual void Seek(int64_t value) override
BmnBinaryFileProcessingOptions
Definition json.hpp:4446