GCC Code Coverage Report


source/XpertMassCore/src/
File: source/XpertMassCore/src/MassDataCborBaseHandler.cpp
Date: 2025-11-20 01:41:33
Lines:
0/80
0.0%
Functions:
0/16
0.0%
Branches:
0/66
0.0%

Line Branch Exec Source
1 /* BEGIN software license
2 *
3 * MsXpertSuite - mass spectrometry software suite
4 * -----------------------------------------------
5 * Copyright (C) 2009--2020 Filippo Rusconi
6 *
7 * http://www.msxpertsuite.org
8 *
9 * This file is part of the MsXpertSuite project.
10 *
11 * The MsXpertSuite project is the successor of the massXpert project. This
12 * project now includes various independent modules:
13 *
14 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
15 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
16 *
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *
30 * END software license
31 */
32
33
34 /////////////////////// Std lib includes
35
36
37 /////////////////////// Qt includes
38 #include <QDebug>
39 #include <QFileInfo>
40
41
42 /////////////////////// IsoSpec
43
44
45 /////////////////////// Local includes
46 #include "MsXpS/libXpertMassCore/MassDataCborBaseHandler.hpp"
47
48 namespace MsXpS
49 {
50
51 namespace libXpertMassCore
52 {
53
54
55 /*!
56 \class MsXpS::libXpertMassCore::MassDataCborBaseHandler
57 \inmodule libXpertMassCore
58 \ingroup XpertMassCoreUtilities
59 \inheaderfile MassDataCborBaseHandler.hpp
60
61 \brief The MassDataCborBaseHandler class provides features to handle
62 mass spectrometric data using the CBOR (Concise Binary Object Representation)
63 container streaming classes.
64
65 The data transported using CBOR is first qualified using the \l{Enums::MassDataType}
66 enum. The data are packed following that mass data type specification.
67 */
68
69
70
71 /*!
72 \brief Constructs a MassDataCborBaseHandler instance setting parent to \a
73 parent_p.
74 */
75 MassDataCborBaseHandler::MassDataCborBaseHandler(QObject *parent_p)
76 : QObject(parent_p)
77 {
78 }
79
80 /*!
81 \brief Destructs the MassDataCborBaseHandler instance.
82 */
83 MassDataCborBaseHandler::~MassDataCborBaseHandler()
84 {
85 }
86
87 /*!
88 \brief Sets the input file name to \a file_name.
89 */
90 void
91 MassDataCborBaseHandler::setInputFileName(const QString &file_name)
92 {
93 m_inputFileName = file_name;
94 }
95
96 /*!
97 \brief Sets the output file name to \a file_name.
98 */
99 void
100 MassDataCborBaseHandler::setOutputFileName(const QString &file_name)
101 {
102 m_outputFileName = file_name;
103 }
104
105 /*!
106 \brief Sets the mass data type to \a mass_data_type.
107 */
108 void
109 MassDataCborBaseHandler::setMassDataType(Enums::MassDataType mass_data_type)
110 {
111 m_massDataType = mass_data_type;
112 }
113
114 /*!
115 \brief Returns the mass data type.
116 */
117 Enums::MassDataType
118 MassDataCborBaseHandler::getMassDataType() const
119 {
120 return m_massDataType;
121 }
122
123 /*!
124 \brief Decodes the data stream from \a reader_sp.
125
126 \note The base class does nothing and always returns false.
127 */
128 bool
129 MassDataCborBaseHandler::decodeStream(
130 [[maybe_unused]] QCborStreamReaderSPtr &reader_sp)
131 {
132 qDebug() << "The base class handler function does nothing.";
133 return false;
134 }
135
136 /*!
137 \brief Decodes enough of the data streamed by \a reader_sp to determine and
138 return the mass data type of the streamed data.
139
140 \note Failure to decode the mass data type is fatal.
141 */
142 Enums::MassDataType
143 MassDataCborBaseHandler::readMassDataType(QCborStreamReaderSPtr &reader_sp)
144 {
145 QString current_key;
146
147 // The file format starts with a quint64 that indicates the type of mass
148 // data (MassDataType enum to quint64).
149
150 while(!reader_sp->lastError() && reader_sp->hasNext())
151 {
152 // The first iteration in the CBOR data structure is in a map.
153
154 QCborStreamReader::Type type = reader_sp->type();
155 // qDebug() << "Type is:" << type;
156
157 if(type != QCborStreamReader::Map)
158 qFatal(
159 "The byte array does not have the expected CBOR structure for "
160 "mass data.");
161
162 reader_sp->enterContainer();
163
164 while(reader_sp->lastError() == QCborError::NoError &&
165 reader_sp->hasNext())
166 {
167 QCborStreamReader::Type type = reader_sp->type();
168 // qDebug() << "Type is:" << type;
169
170 // The very first item of the map should be a pair
171 //
172 // "DATA_TYPE / quint64
173
174 if(type == QCborStreamReader::String)
175 {
176 // Read a CBOR string, concatenating all
177 // the chunks into a single string.
178 QString str;
179 auto chunk = reader_sp->readString();
180 while(chunk.status == QCborStreamReader::Ok)
181 {
182 str += chunk.data;
183 chunk = reader_sp->readString();
184 }
185
186 if(chunk.status == QCborStreamReader::Error)
187 {
188 // handle error condition
189 qDebug() << "There was an error reading string chunk.";
190 str.clear();
191 }
192
193 // qDebug() << "The string that was read:" << str;
194
195 // If the current key is empty, this string value is a new key
196 // or tag. Otherwise, it's a value.
197
198 if(current_key.isEmpty())
199 {
200 // qDebug() << "Setting current_key:" << str;
201 current_key = str;
202 }
203 else
204 {
205 // At this point we can reset current_key.
206 current_key = QString();
207 }
208 }
209 else if(type == QCborStreamReader::UnsignedInteger)
210 {
211 if(current_key != "DATA_TYPE")
212 qFatal(
213 "The byte array does not have the expected CBOR "
214 "structure for "
215 "mass data.");
216
217 // quint64 data_type = reader_sp->toUnsignedInteger();
218 // qDebug() << "The mass data type:" << data_type;
219
220 return static_cast<Enums::MassDataType>(
221 reader_sp->toUnsignedInteger());
222 }
223 else
224 qFatal(
225 "The byte array does not have the expected CBOR "
226 "structure for mass data.");
227 }
228 }
229
230 return Enums::MassDataType::NOT_SET;
231 }
232
233 /*!
234 \overload
235
236 \brief Decodes enough of the data contained in file \a input_file_name to
237 determine and return the mass data type of the streamed data.
238
239 \note Failure to decode the mass data type is fatal.
240
241 \sa readMassDataType() overloads
242 */
243 Enums::MassDataType
244 MassDataCborBaseHandler::readMassDataType(const QString &input_file_name)
245 {
246 QFileInfo file_info(input_file_name);
247
248 if(!file_info.exists())
249 {
250 qDebug() << "File not found.";
251 return Enums::MassDataType::NOT_SET;
252 }
253
254 QFile file(input_file_name);
255
256 bool res = file.open(QIODevice::ReadOnly);
257
258 if(!res)
259 {
260 qDebug() << "Failed to open the file for read.";
261 return Enums::MassDataType::NOT_SET;
262 }
263
264 QCborStreamReaderSPtr reader_sp = std::make_shared<QCborStreamReader>(&file);
265
266 return readMassDataType(reader_sp);
267 }
268
269 /*!
270 \overload
271
272 \brief Decodes enough of the data contained in \a byte_array to
273 determine and return the mass data type of the streamed data.
274
275 \note Failure to decode the mass data type is fatal.
276
277 \sa readMassDataType() overloads
278 */
279 Enums::MassDataType
280 MassDataCborBaseHandler::readMassDataType(const QByteArray &byte_array)
281 {
282 QCborStreamReaderSPtr reader_sp =
283 std::make_shared<QCborStreamReader>(byte_array);
284
285 return readMassDataType(reader_sp);
286 }
287
288 /*!
289 \brief Reads the data in file \a input_file_name by decoding the data stream
290 read from it.
291
292 \note The base class does nothing and always returns false.
293 */
294 bool
295 MassDataCborBaseHandler::readFile(
296 [[maybe_unused]] const QString &input_file_name)
297 {
298 qDebug() << "The base class handler function does nothing.";
299 return false;
300 }
301
302 /*!
303 \brief Reads the data in byte array \a byte_array by decoding the data stream
304 read from it.
305
306 \note The base class does nothing and always returns false.
307 */
308 bool
309 MassDataCborBaseHandler::readByteArray(
310 [[maybe_unused]] const QByteArray &byte_array)
311 {
312 qDebug() << "The base class handler function does nothing.";
313 return false;
314 }
315
316 /*!
317 \brief Writes member data to file \a output_file_name.
318
319 \note The base class does nothing and always returns false.
320 */
321 bool
322 MassDataCborBaseHandler::writeFile(
323 [[maybe_unused]] const QString &output_file_name)
324 {
325 qDebug() << "The base class handler function does nothing.";
326 return false;
327 }
328
329 /*!
330 \brief Writes member data to byte array \a byte_array.
331
332 \note The base class does nothing and always returns false.
333 */
334 void
335 MassDataCborBaseHandler::writeByteArray([[maybe_unused]] QByteArray &byte_array)
336 {
337 qDebug() << "The base class handler function does nothing.";
338 }
339
340 /*!
341 \brief Sets the \a title of the mass data entity carried by the CBOR container.
342 */
343 void
344 MassDataCborBaseHandler::setTitle(const QString &title)
345 {
346 m_title = title;
347 }
348
349 /*!
350 \brief Returns the title of the mass data entity carried by the CBOR container.
351 */
352 QString
353 MassDataCborBaseHandler::getTitle() const
354 {
355 return m_title;
356 }
357
358
359 } // namespace libXpertMassCore
360
361 } // namespace MsXpS
362