libxcks  0.1.0.1
xcksreader.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/xcksreader.hpp"
32 #include "xcksfilereader.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 // XCKSReader
50 //###########################################################################
51 
52 /*
53  * Constructor.
54  */
55 XCKSReader::XCKSReader(XCKSReaderHandler& xcksReaderHandler) : readerHandler(xcksReaderHandler)
56 {
57 }
58 //---------------------------------------------------------------------------
59 
60 
61 /*
62  * Destructor.
63  */
65 {
66 }
67 //---------------------------------------------------------------------------
68 
69 
70 /*
71  * Parses an XCKS file from an input stream.
72  */
73 bool XCKSReader::parse(std::istream& is, const std::filesystem::path& basePath)
74 {
75  if (!basePath.is_absolute())
76  {
77  readerHandler.onFatalError((format(translate("The base path {1} must be an absolute path.").str(libxcks_domain))
78  % from_u8string(basePath.u8string())).str(), -1 , -1);
79  return false;
80  }
81 
83  return reader.parse(is);
84 }
85 //---------------------------------------------------------------------------
86 
87 
88 /*
89  * Parses an XCKS file from a file.
90  */
91 bool XCKSReader::parse(const std::filesystem::path& fileFullPath)
92 {
93  if (!fileFullPath.is_absolute())
94  {
95  readerHandler.onFatalError((format(translate("The file path {1} must be an absolute path.").str(libxcks_domain))
96  % from_u8string(fileFullPath.u8string())).str(), -1, -1);
97  return false;
98  }
99 
100  ifstream is(fileFullPath, ios_base::in | ios_base::binary);
101  if (!is.is_open())
102  {
103  readerHandler.onFatalError((format(translate("Can't open {1}.").str(libxcks_domain))
104  % from_u8string(fileFullPath.u8string())).str(), -1, -1);
105  return false;
106  }
107 
108  return parse(is, fileFullPath.parent_path());
109 }
110 //---------------------------------------------------------------------------
111 
112 
113 /*
114  * Parses an XCKS file from a file and a base path.
115  */
116 bool XCKSReader::parse(const std::filesystem::path& filePath,
117  const std::filesystem::path& basePath)
118 {
119  if (!basePath.is_absolute())
120  {
121  readerHandler.onFatalError((format(translate("The base path {1} must be an absolute path.").str(libxcks_domain))
122  % from_u8string(basePath.u8string())).str(), -1, -1);
123  return false;
124  }
125 
126  ifstream is(filePath, ios_base::in | ios_base::binary);
127  if (!is.is_open())
128  {
129  readerHandler.onFatalError((format(translate("Can't open {1}.").str(libxcks_domain))
130  % from_u8string(filePath.u8string())).str(), -1, -1);
131  return false;
132  }
133 
134  return parse(is, basePath);
135 }
136 //---------------------------------------------------------------------------
137 
138 
139 /*
140  * Convenience method for parsing an XCKS file from an input stream.
141  */
142 bool XCKSReader::parseXCKS(XCKSReaderHandler& xcksReaderHandler, std::istream& is,
143  const std::filesystem::path& basePath)
144 {
145  XCKSReader reader(xcksReaderHandler);
146  return reader.parse(is, basePath);
147 }
148 //---------------------------------------------------------------------------
149 
150 
151 /*
152  * Convenience method for parsing an XCKS file from a file.
153  */
154 bool XCKSReader::parseXCKS(XCKSReaderHandler& xcksReaderHandler,
155  const std::filesystem::path& fileFullPath)
156 {
157  XCKSReader reader(xcksReaderHandler);
158  return reader.parse(fileFullPath);
159 }
160 //---------------------------------------------------------------------------
161 
162 
163 /*
164  * Convenience method for parsing an XCKS file from a file and a base path.
165  */
166 bool XCKSReader::parseXCKS(XCKSReaderHandler& xcksReaderHandler,
167  const std::filesystem::path& filePath,
168  const std::filesystem::path& basePath)
169 {
170  XCKSReader reader(xcksReaderHandler);
171  return reader.parse(filePath, basePath);
172 }
173 //---------------------------------------------------------------------------
174 
175 
176 
177 
178 //###########################################################################
179 // ZXCKSReader
180 //###########################################################################
181 
182 /*
183  * Constructor.
184  */
186  XCKSReader(xcksReaderHandler)
187 {
188 }
189 //---------------------------------------------------------------------------
190 
191 
192 /*
193  * Destructor.
194  */
196 {
197 }
198 //---------------------------------------------------------------------------
199 
200 
201 /*
202  * Parses an ZXCKS file from an input stream.
203  */
204 bool ZXCKSReader::parse(istream& is, const std::filesystem::path& basePath)
205 {
206  boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
207  inbuf.push(boost::iostreams::gzip_decompressor());
208  inbuf.push(is);
209  istream instream(&inbuf);
210 
211  // Try to peek a character to see if the stream is a gzip stream.
213  bool res = true;
214  try
215  {
216  instream.peek();
217  res = instream.good();
218  }
219  catch (const boost::iostreams::gzip_error& e)
220  {
221  res = false;
222  readerHandler.onFatalError(e.what(), -1, -1);
223  }
224  catch (const exception& e)
225  {
226  res = false;
227  readerHandler.onFatalError(e.what(), -1, -1);
228  }
229 
230  return res ? XCKSReader::parse(instream, basePath) : res;
231 }
232 //---------------------------------------------------------------------------
233 
234 
235 /*
236  * Convenience method for parsing an ZXCKS file from an input stream.
237  */
239  std::istream& is, const std::filesystem::path& basePath)
240 {
241  ZXCKSReader reader(xcksReaderHandler);
242  return reader.parse(is, basePath);
243 }
244 //---------------------------------------------------------------------------
245 
246 
247 /*
248  * Convenience method for parsing an ZXCKS file from a file.
249  */
251  const std::filesystem::path& fileFullPath)
252 {
253  ZXCKSReader reader(xcksReaderHandler);
254  return reader.parse(fileFullPath);
255 }
256 //---------------------------------------------------------------------------
257 
258 
259 /*
260  * Convenience method for parsing an ZXCKS file from a file and a base path.
261  */
263  const std::filesystem::path& filePath,
264  const std::filesystem::path& basePath)
265 {
266  ZXCKSReader reader(xcksReaderHandler);
267  return reader.parse(filePath, basePath);
268 }
269 //---------------------------------------------------------------------------
270 } // namespace libxcks
271 //---------------------------------------------------------------------------
Handler for reading XCKS files.
Definition: handlers.hpp:50
virtual void onFatalError(const std::string &errorMessage, int line, int column)=0
Called on a non-recoverable error.
XCKS file reader.
Definition: xcksreader.hpp:46
virtual bool parse(std::istream &is, const std::filesystem::path &basePath)
Parses an XCKS file from an input stream.
Definition: xcksreader.cpp:73
static bool parseXCKS(XCKSReaderHandler &xcksReaderHandler, std::istream &is, const std::filesystem::path &basePath)
Convenience method for parsing an XCKS file from an input stream.
Definition: xcksreader.cpp:142
XCKSReaderHandler & readerHandler
The XCKS file reader handler.
Definition: xcksreader.hpp:48
virtual ~XCKSReader()
Destructor.
Definition: xcksreader.cpp:64
bool parse(const std::string &filename)
Parses the given file.
Definition: xmlparser.cpp:544
ZXCKS file reader.
Definition: xcksreader.hpp:176
virtual bool parse(std::istream &is, const std::filesystem::path &basePath)
Parses an XCKS file from an input stream.
Definition: xcksreader.cpp:73
bool parse(std::istream &is, const std::filesystem::path &basePath) override
Parses an ZXCKS file from an input stream.
Definition: xcksreader.cpp:204
ZXCKSReader()=delete
Deleted default constructor.
static bool parseZXCKS(XCKSReaderHandler &xcksReaderHandler, std::istream &is, const std::filesystem::path &basePath)
Convenience method for parsing an ZXCKS file from an input stream.
Definition: xcksreader.cpp:238
virtual ~ZXCKSReader()
Destructor.
Definition: xcksreader.cpp:195
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.
Classes that read a XCKS file.
(Z)XCKS files reader.