BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnCompressionGlobalFunctions.cxx
Go to the documentation of this file.
1// headers from this target
2#include "BmnCompressionGlobalFunctions.h"
3
4#include "BmnDefinitions.h"
5#include "BmnFileReaderRaw.h"
6#include "BmnFileReaderXzLzma.h"
7#include "BmnFileReaderZLib.h"
8#include "BmnFileReaderZLibNG.h"
9#include "BmnFileReaderZStd.h"
10// std:: headers
11#include <algorithm>
12#include <array>
13#include <cctype>
14#include <iterator>
15#include <string>
16#ifdef BMNCOMPRESSION_WITH_ZSTD
17#include <zstd.h>
18#endif // BMNCOMPRESSION_WITH_ZSTD
19
20// 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
21// ================== static function declaration ==================
22// 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
23
24/*
25 * A translation-unit function that will be updated as we add new reading libraries. This function
26 * opens a stream for the provided path (if one exists) and based on magic bytes, it returns what kind
27 * of file reader should be created
28 * @param aFilePath A path to an existing actual and accessible file that should be read
29 * @param aUserSelectedAlgorithm A preferred algorithm selected by a user and passed into
30 * `BmnCompressionIsArchiveLibAvailable`
31 * @return A type of the file that should be opened
32 */
33[[nodiscard]] static BmnFileType DoCommonProcessingOfFileFinding(const std::filesystem::path& aFilePath,
34 const BmnFileType aUserSelectedAlgorithm);
35
36// 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
37// ================== Global functions ==================
38// 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
39
40bool BmnCompressionIsArchiveLibAvailable(const BmnFileType aLibraryType) noexcept
41{
42 switch (aLibraryType) {
44#ifdef BMNCOMPRESSION_WITH_ZSTD
45 return true;
46#else
47 return false;
48#endif // BMNCOMPRESSION_WITH_ZSTD
50#ifdef BMNCOMPRESSION_WITH_ZLIB
51 return true;
52#else
53 return false;
54#endif // BMNCOMPRESSION_WITH_ZLIB
56#ifdef BMNCOMPRESSION_WITH_ZLIB_NG
57 return true;
58#else
59 return false;
60#endif // BMNCOMPRESSION_WITH_ZLIB_NG
62#ifdef BMNCOMPRESSION_WITH_XZ_LZMA
63 return true;
64#else
65 return false;
66#endif // BMNCOMPRESSION_WITH_XZ_LZMA
68 return true;
70 default:
71 return false;
72 }
73}
74
75BmnIFileReader* BmnCompressionCreateNewSuitableReaderForAFile(const std::filesystem::path& aFilePath,
76 const BmnFileType aPreferredTypeForThisAlgorithm)
77{
78 BmnFileType aNeededType = DoCommonProcessingOfFileFinding(aFilePath, aPreferredTypeForThisAlgorithm);
79 switch (aNeededType) {
80#ifdef BMNCOMPRESSION_WITH_ZSTD
82 return new BmnFileReaderZStd{aFilePath};
83#endif // BMNCOMPRESSION_WITH_ZSTD
84#ifdef BMNCOMPRESSION_WITH_ZLIB
86 return new BmnFileReaderZLib{aFilePath};
87#endif // BMNCOMPRESSION_WITH_ZLIB
88#ifdef BMNCOMPRESSION_WITH_ZLIB_NG
90 return new BmnFileReaderZLibNG{aFilePath};
91#endif // BMNCOMPRESSION_WITH_ZLIB_NG
92#ifdef BMNCOMPRESSION_WITH_XZ_LZMA
94 return new BmnFileReaderXzLzma{aFilePath};
95#endif // BMNCOMPRESSION_WITH_XZ_LZMA
97 return new BmnFileReaderRaw{aFilePath};
99 default:
100 return nullptr;
101 }
102}
103
105 const BmnFileType aPreferredTypeForThisAlgorithm)
106{
107 BmnFileType aNeededType = DoCommonProcessingOfFileFinding(aFilePath, aPreferredTypeForThisAlgorithm);
108 switch (aNeededType) {
110#ifdef BMNCOMPRESSION_WITH_ZSTD
111 return new BmnFileReaderZStd{std::move(aFilePath)};
112#endif // BMNCOMPRESSION_WITH_ZSTD
113#ifdef BMNCOMPRESSION_WITH_ZLIB
115 return new BmnFileReaderZLib{std::move(aFilePath)};
116#endif // BMNCOMPRESSION_WITH_ZLIB
117#ifdef BMNCOMPRESSION_WITH_ZLIB_NG
119 return new BmnFileReaderZLibNG{std::move(aFilePath)};
120#endif // BMNCOMPRESSION_WITH_ZLIB_NG
121#ifdef BMNCOMPRESSION_WITH_XZ_LZMA
123 return new BmnFileReaderXzLzma{std::move(aFilePath)};
124#endif // BMNCOMPRESSION_WITH_XZ_LZMA
125 case BmnFileType::Raw:
126 return new BmnFileReaderRaw{std::move(aFilePath)};
128 default:
129 return nullptr;
130 }
131}
132
133std::filesystem::path BmnCompressionRemoveArchiveExtension(std::filesystem::path aFilePath)
134{
135 std::string fileExtension = aFilePath.extension().string();
136 // '.ZST' names the very same format as '.zst', so the extensions are compared in the lower case
137 std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(),
138 [](unsigned char aSymbol) { return static_cast<char>(std::tolower(aSymbol)); });
139
140 // the list of the archive extensions is declared in BmnCompressionGlobalFunctions.h
141 if (std::find(std::cbegin(BmnCompressionArchiveExtensions), std::cend(BmnCompressionArchiveExtensions),
142 fileExtension)
144 return aFilePath;
145
146 return aFilePath.replace_extension();
147}
148
149// 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
150// ================== static function definition ==================
151// 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
152
154static BmnFileType DoCommonProcessingOfFileFinding(const std::filesystem::path& aFilePath,
155 const BmnFileType aUserSelectedAlgorithm)
156{
157 if (aFilePath.empty()) {
158 LOG(error) << "You did not provide a path for opening a file reader!\n";
160 }
161 try {
162 if (!std::filesystem::exists(aFilePath) || !std::filesystem::is_regular_file(aFilePath)) {
163 LOG(error) << "You should provide an existing path to an actual file for opening a file reader!\n";
165 }
166 } catch (const std::bad_alloc& errorDescription) {
167 LOG(error) << "Filesystem failure! Reason: " << errorDescription.what() << '\n';
169 } catch (const std::filesystem::filesystem_error& errorDescription) {
170 LOG(error) << "Filesystem failure! Reason: " << errorDescription.what() << '\n';
172 }
173 std::ifstream inStream{};
174 inStream.open(aFilePath, std::ios::in | std::ios::binary);
175 if (!inStream.is_open()) {
176 LOG(error) << "Failed to open a file for checking a magic byte for opening a file reader!\n";
178 }
179 std::array<char, 15> beginningOfTheStream{};
180 inStream.read(beginningOfTheStream.data(), beginningOfTheStream.size());
181 // ================================================================================================================
182#ifdef BMNCOMPRESSION_WITH_ZSTD
183 if (*reinterpret_cast<uint32_t*>(beginningOfTheStream.data()) == ZSTD_MAGICNUMBER)
184 return BmnFileType::ZStd;
185#endif // BMNCOMPRESSION_WITH_ZSTD
186 // ================================================================================================================
187#ifdef BMNCOMPRESSION_WITH_XZ_LZMA
188 // I don't see this information in the XZ_LZMA API. Still, I found it on the internet and seems to work
189 constexpr char xzMagicByte[7] = {"\xFD\x37\x7A\x58\x5A\x00"};
190 for (size_t i = 0ull; i < 6; ++i) {
191 if (beginningOfTheStream[i] != xzMagicByte[i])
192 break;
193 // if we are here in the last pass, it means we have a match
194 if (i == 5)
196 }
197#endif // BMNCOMPRESSION_WITH_XZ_LZMA
198 // ================================================================================================================
199#if defined(BMNCOMPRESSION_WITH_ZLIB) || defined(BMNCOMPRESSION_WITH_ZLIB_NG)
200 // for now we expect GZip compression while later we might add additional support for files compressed directly by
201 // us. the deflate format itself doesn't have a magic byte, while zlib has various headers, but we will not be
202 // writing a direct ZLIB stream anyway
203 if (beginningOfTheStream[0] == '\x1F' && beginningOfTheStream[1] == '\x8B') {
204#ifdef BMNCOMPRESSION_WITH_ZLIB_NG
205#ifdef BMNCOMPRESSION_WITH_ZLIB
206 if (aUserSelectedAlgorithm == BmnFileType::ZLib)
207 return BmnFileType::ZLib;
208#endif // BMNCOMPRESSION_WITH_ZLIB
210#else // defined(BMNCOMPRESSION_WITH_ZLIB) && !defined(BMNCOMPRESSION_WITH_ZLIB_NG)
211 return BmnFileType::ZLib;
212#endif // BMNCOMPRESSION_WITH_ZLIB_NG
213 }
214#endif // defined(BMNCOMPRESSION_WITH_ZLIB) || defined(BMNCOMPRESSION_WITH_ZLIB_NG)
215 // ================================================================================================================
216 return BmnFileType::Raw;
217}
bool BmnCompressionIsArchiveLibAvailable(const BmnFileType aLibraryType) noexcept
static BmnFileType DoCommonProcessingOfFileFinding(const std::filesystem::path &aFilePath, const BmnFileType aUserSelectedAlgorithm)
std::filesystem::path BmnCompressionRemoveArchiveExtension(std::filesystem::path aFilePath)
BmnIFileReader * BmnCompressionCreateNewSuitableReaderForAFile(const std::filesystem::path &aFilePath, const BmnFileType aPreferredTypeForThisAlgorithm)
int i
Definition P4_F32vec4.h:22
#define RESTORE_UNUSED_PARAM_WARNING
#define DISABLE_UNUSED_PARAM_WARNING
constexpr std::string_view BmnCompressionArchiveExtensions[]