libxcks  0.1.0.1
xckswriter.cpp
Go to the documentation of this file.
1 /*
2  * libxcks
3  * Copyright (C) 2022 Julien Couot
4  *
5  * This program is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
13  * License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
25 //---------------------------------------------------------------------------
26 #include <fstream>
27 #include <boost/iostreams/filtering_streambuf.hpp>
28 #include <boost/iostreams/filter/gzip.hpp>
29 #include <boost/locale.hpp>
30 
31 #include "libxcks/xckswriter.hpp"
32 #include "xcksfilewriter.hpp"
33 #include "strutil.hpp"
34 #include "pathutil.hpp"
35 //---------------------------------------------------------------------------
36 
37 
39 using namespace std;
40 
42 using namespace boost::locale;
43 //---------------------------------------------------------------------------
44 
45 
46 namespace libxcks
47 {
48 //###########################################################################
49 // XCKSWriter
50 //###########################################################################
51 
52 /*
53  * Constructor.
54  */
55 XCKSWriter::XCKSWriter(XCKSWriterHandler& xcksWriterHandler,
56  XCKSWriterChecksumProvider& checksumProvider,
57  const XCKSWriterOptions& options,
58  const Version version,
59  const ArrayChecksumAlgoId& algoIds,
60  const ChecksumFormatter::ConfigurationProvider& ckftConfProvider) :
61  writerHandler(xcksWriterHandler),
62  ckProvider(checksumProvider),
63  writerOptions(options),
64  version(version),
65  sumsAlgos(algoIds),
66  ckfConfProvider(ckftConfProvider)
67 {
68 }
69 //---------------------------------------------------------------------------
70 
71 
72 /*
73  * Destructor.
74  */
76 {
77 }
78 //---------------------------------------------------------------------------
79 
80 
81 /*
82  * Writes an XCKS file to an output stream.
83  */
84 bool XCKSWriter::write(std::ostream& os, const std::filesystem::path& basePath,
85  const ArrayPath& relativePaths)
86 {
87  if (checkBaseDirAndPathList(basePath, relativePaths))
88  return doWrite(os, basePath, relativePaths);
89  else
90  return false;
91 }
92 //---------------------------------------------------------------------------
93 
94 
95 /*
96  * Writes an XCKS file to a file.
97  */
98 bool XCKSWriter::write(const std::filesystem::path& fileFullPath,
99  const ArrayPath& relativePaths)
100 {
101  if (!fileFullPath.is_absolute())
102  {
103  writerHandler.onFatalError((format(translate("The file path {1} must be an absolute path.").str(libxcks_domain))
104  % from_u8string(fileFullPath.u8string())).str());
105  return false;
106  }
107 
108  if (checkBaseDirAndPathList(fileFullPath.parent_path(), relativePaths))
109  {
110  ofstream os(fileFullPath, ios_base::out | ios_base::binary);
111  if (!os.is_open())
112  {
113  writerHandler.onFatalError((format(translate("Can't open {1}.").str(libxcks_domain))
114  % from_u8string(fileFullPath.u8string())).str());
115  return false;
116  }
117 
118  return doWrite(os, fileFullPath.parent_path(), relativePaths);
119  }
120  else
121  return false;
122 }
123 //---------------------------------------------------------------------------
124 
125 
126 /*
127  * Writes an XCKS file to a file with a different base path.
128  */
129 bool XCKSWriter::write(const std::filesystem::path& filePath,
130  const std::filesystem::path& basePath,
131  const ArrayPath& relativePaths)
132 {
133  if (checkBaseDirAndPathList(basePath, relativePaths))
134  {
135  ofstream os(filePath, ios_base::out | ios_base::binary);
136  if (!os.is_open())
137  {
138  writerHandler.onFatalError((format(translate("Can't open {1}.").str(libxcks_domain))
139  % from_u8string(filePath.u8string())).str());
140  return false;
141  }
142 
143  return doWrite(os, basePath, relativePaths);
144  }
145  else
146  return false;
147 }
148 //---------------------------------------------------------------------------
149 
150 
151 /*
152  * Checks if the provided base directory has an absolute path and the files
153  * to add to the XCKS file have all a relative path.
154  *
155  * @return @c true if the upper requirements are met, @c false otherwise.
156  */
157 bool XCKSWriter::checkBaseDirAndPathList(const filesystem::path& basePath,
158  const ArrayPath& relativePaths) const
159 {
160  if (!basePath.is_absolute())
161  {
162  writerHandler.onFatalError((format(translate("The base path {1} must be an absolute path.").str(libxcks_domain))
163  % from_u8string(basePath.u8string())).str());
164  return false;
165  }
166 
167  bool allRelative = true;
168  ArrayPath::const_iterator it = relativePaths.cbegin();
169  while (allRelative && it != relativePaths.cend())
170  {
171  if (it->is_relative())
172  ++it;
173  else
174  allRelative = false;
175  }
176  if (!allRelative)
177  {
178  writerHandler.onFatalError(translate("All provided paths of files must be relative.").str(libxcks_domain));
179  return false;
180  }
181 
182  return true;
183 }
184 //---------------------------------------------------------------------------
185 
186 
187 /*
188  * Writes an XCKS file to an output stream.
189  */
190 bool XCKSWriter::doWrite(ostream& os, const filesystem::path& basePath,
191  const ArrayPath& relativePaths)
192 {
196  if (writer.getChecksumTypesForNewEntries().empty())
197  return false;
198 
199  return writer.write(os, relativePaths);
200 }
201 //---------------------------------------------------------------------------
202 
203 
204 
205 
206 //###########################################################################
207 // XCKSWriter
208 //###########################################################################
209 
210 /*
211  * Constructor.
212  */
214  XCKSWriterChecksumProvider& checksumProvider,
215  const ZXCKSWriterOptions& options,
216  const Version version,
217  const ArrayChecksumAlgoId& algoIds,
218  const ChecksumFormatter::ConfigurationProvider& ckftConfProvider) :
219  XCKSWriter(xcksWriterHandler, checksumProvider,
220  options, version, algoIds, ckftConfProvider)
221 {
222 }
223 //---------------------------------------------------------------------------
224 
225 
226 /*
227  * Destructor.
228  */
230 {
231 }
232 //---------------------------------------------------------------------------
233 
234 
235 /*
236  * Writes a ZXCKS file to an output stream.
237  */
238 bool ZXCKSWriter::doWrite(ostream& os, const filesystem::path& basePath,
239  const ArrayPath& relativePaths)
240 {
241  boost::iostreams::filtering_streambuf<boost::iostreams::output> outbuf;
242  outbuf.push(boost::iostreams::gzip_compressor(dynamic_cast<const ZXCKSWriterOptions&>(writerOptions).getCompressionLevel()));
243  outbuf.push(os);
244  ostream outstream(&outbuf);
245 
246  bool res = XCKSWriter::doWrite(outstream, basePath, relativePaths);
247 
248  // Closing GZip stream.
249  boost::iostreams::close(outbuf);
250 
251  return res;
252 }
253 //---------------------------------------------------------------------------
254 
255 } // namespace libxcks
256 //---------------------------------------------------------------------------
Configuration provider for ChecksumFormatter.
Definition: ckformatter.hpp:69
A XCKS file writer.
ArrayChecksumAlgoId getChecksumTypesForNewEntries() const
Returns the list of checksums algorithms to compute for new entries of this type of checksums' file.
bool write(std::ostream &os, const ArrayPath &relativePaths)
Writes the checksums in a stream.
Provides checksums values from an array of wanted algorithms of checksums for the XCKS writer.
Definition: handlers.hpp:375
Handler for writing XCKS files.
Definition: handlers.hpp:423
virtual void onFatalError(const std::string &errorMessage)=0
Called on a non-recoverable error.
Provides options for the XCKS writer.
Definition: handlers.hpp:818
XCKS file writer.
Definition: xckswriter.hpp:47
virtual bool doWrite(std::ostream &os, const std::filesystem::path &basePath, const ArrayPath &relativePaths)
Writes an XCKS file to an output stream.
Definition: xckswriter.cpp:190
const ArrayChecksumAlgoId sumsAlgos
Type of algorithms' checksums to write for each file.
Definition: xckswriter.hpp:53
const Version version
Version of the (Z)XCKS file to write.
Definition: xckswriter.hpp:52
virtual ~XCKSWriter()
Destructor.
Definition: xckswriter.cpp:75
bool write(std::ostream &os, const std::filesystem::path &basePath, const ArrayPath &relativePaths)
Writes an XCKS file to an output stream.
Definition: xckswriter.cpp:84
XCKSWriterChecksumProvider & ckProvider
The provider of checksums values.
Definition: xckswriter.hpp:50
XCKSWriterHandler & writerHandler
The XCKS file writer handler.
Definition: xckswriter.hpp:49
const ChecksumFormatter::ConfigurationProvider & ckfConfProvider
Configuration provider for ChecksumFormatter.
Definition: xckswriter.hpp:54
const XCKSWriterOptions & writerOptions
The writer options.
Definition: xckswriter.hpp:51
Provides options for the XCKS writer.
Definition: handlers.hpp:1071
virtual ~ZXCKSWriter()
Destructor.
Definition: xckswriter.cpp:229
ZXCKSWriter()=delete
Deleted default constructor.
bool doWrite(std::ostream &os, const std::filesystem::path &basePath, const ArrayPath &relativePaths) override
Writes a ZXCKS file to an output stream.
Definition: xckswriter.cpp:238
constexpr const char * libxcks_domain
Domain for translations (i18n).
Definition: defs.hpp:47
std::filesystem::path ensureEndsWithPathSeparator(const std::filesystem::path &p)
Ensures the path ends with a path separator.
Definition: pathutil.cpp:209
Path utilities.
std::string from_u8string(const std::string &s)
Returns an UTF-8 encoded string in an object of type std::string (C++17).
Definition: strutil.cpp:217
String utilities.
std::vector< ChecksumAlgoId > ArrayChecksumAlgoId
Array of ids of algorithms of checksums.
Definition: types.hpp:92
std::vector< std::filesystem::path > ArrayPath
Array of paths.
Definition: types.hpp:49
Version
Known versions of XCKS file.
Definition: types.hpp:55
Classes that write a XCKS file.
(Z)XCKS files writer.