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