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