| 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 "MassDataCborMassSpectrumHandler.hpp" | ||
| 47 | |||
| 48 | |||
| 49 | namespace MsXpS | ||
| 50 | { | ||
| 51 | |||
| 52 | namespace libXpertMass | ||
| 53 | { | ||
| 54 | |||
| 55 | // FIXME TODO DOCUMENTATION | ||
| 56 | |||
| 57 | ✗ | MassDataCborMassSpectrumHandler::MassDataCborMassSpectrumHandler( | |
| 58 | ✗ | QObject *parent_p) | |
| 59 | ✗ | : MassDataCborBaseHandler(parent_p) | |
| 60 | { | ||
| 61 | ✗ | } | |
| 62 | |||
| 63 | |||
| 64 | // When providing a Trace, it is implicit that this is to write that to file. | ||
| 65 | ✗ | MassDataCborMassSpectrumHandler::MassDataCborMassSpectrumHandler( | |
| 66 | ✗ | QObject *parent_p, const pappso::Trace &trace) | |
| 67 | ✗ | : MassDataCborBaseHandler(parent_p), m_trace(trace) | |
| 68 | { | ||
| 69 | ✗ | } | |
| 70 | |||
| 71 | |||
| 72 | ✗ | MassDataCborMassSpectrumHandler::~MassDataCborMassSpectrumHandler() | |
| 73 | { | ||
| 74 | ✗ | } | |
| 75 | |||
| 76 | |||
| 77 | bool | ||
| 78 | ✗ | MassDataCborMassSpectrumHandler::writeFile(const QString &output_file_name) | |
| 79 | { | ||
| 80 | // The format for this kind of CBOR pappso::Trace data is the following: | ||
| 81 | |||
| 82 | // First the quint64 that represents MassDataType. In our specific case, that | ||
| 83 | // must be MassDataType::MASS_SPECTRUM. | ||
| 84 | |||
| 85 | // Then there is the title of data, which is according to the specification: | ||
| 86 | // | ||
| 87 | // Major type 3: a text string, specifically a string of Unicode characters | ||
| 88 | // that is encoded as UTF-8 (that is, not a QByteArray, but a QString). | ||
| 89 | |||
| 90 | // Then there is a MAP with the following key/value pairs: | ||
| 91 | |||
| 92 | // start_map | ||
| 93 | |||
| 94 | // "X_LABEL" / value (text string) | ||
| 95 | // "Y_LABEL" / value (text string) | ||
| 96 | // | ||
| 97 | // "X_DATA" / value (base64 ByteArray) | ||
| 98 | // "Y_DATA" / value (base64 ByteArray) | ||
| 99 | |||
| 100 | // end_map | ||
| 101 | |||
| 102 | ✗ | QString local_file_name = output_file_name; | |
| 103 | |||
| 104 | ✗ | if(local_file_name.isEmpty()) | |
| 105 | ✗ | local_file_name = m_outputFileName; | |
| 106 | |||
| 107 | ✗ | QFile file(local_file_name); | |
| 108 | |||
| 109 | ✗ | bool res = file.open(QIODevice::WriteOnly); | |
| 110 | |||
| 111 | ✗ | if(!res) | |
| 112 | { | ||
| 113 | ✗ | qDebug() << "Failed to open the file for write."; | |
| 114 | ✗ | return false; | |
| 115 | } | ||
| 116 | |||
| 117 | ✗ | msp_writer = std::make_shared<QCborStreamWriter>(&file); | |
| 118 | |||
| 119 | // qDebug() << "Now writing data to file:" << local_file_name; | ||
| 120 | |||
| 121 | // Start of array containing all mapped items | ||
| 122 | ✗ | msp_writer->startMap(7); | |
| 123 | |||
| 124 | // First the MassDataType: this is the very *first* data bit in the data | ||
| 125 | // stream. | ||
| 126 | ✗ | msp_writer->append("DATA_TYPE"); | |
| 127 | ✗ | msp_writer->append(static_cast<quint64>(MassDataType::MASS_SPECTRUM)); | |
| 128 | |||
| 129 | ✗ | msp_writer->append("TITLE"); | |
| 130 | ✗ | msp_writer->append(m_title); | |
| 131 | |||
| 132 | ✗ | msp_writer->append("TRACE_COLOR"); | |
| 133 | ✗ | msp_writer->append(m_colorByteArray); | |
| 134 | |||
| 135 | ✗ | msp_writer->append("X_LABEL"); | |
| 136 | ✗ | msp_writer->append("m/z"); | |
| 137 | |||
| 138 | ✗ | msp_writer->append("X_DATA"); | |
| 139 | ✗ | msp_writer->append(m_trace.xAsBase64Encoded()); | |
| 140 | |||
| 141 | ✗ | msp_writer->append("Y_LABEL"); | |
| 142 | ✗ | msp_writer->append("intensity"); | |
| 143 | |||
| 144 | ✗ | msp_writer->append("Y_DATA"); | |
| 145 | ✗ | msp_writer->append(m_trace.yAsBase64Encoded()); | |
| 146 | |||
| 147 | ✗ | msp_writer->endMap(); | |
| 148 | // Close the map now. | ||
| 149 | |||
| 150 | ✗ | file.close(); | |
| 151 | |||
| 152 | ✗ | return res; | |
| 153 | ✗ | } | |
| 154 | |||
| 155 | |||
| 156 | void | ||
| 157 | ✗ | MassDataCborMassSpectrumHandler::writeByteArray(QByteArray &byte_array) | |
| 158 | { | ||
| 159 | ✗ | msp_writer = std::make_shared<QCborStreamWriter>(&byte_array); | |
| 160 | |||
| 161 | // qDebug() << "Now writing data byte array."; | ||
| 162 | |||
| 163 | // Start of array containing all mapped items | ||
| 164 | ✗ | msp_writer->startMap(7); | |
| 165 | |||
| 166 | // First the MassDataType: this is the very *first* data bit in the data | ||
| 167 | // stream. | ||
| 168 | ✗ | msp_writer->append("DATA_TYPE"); | |
| 169 | ✗ | msp_writer->append(static_cast<quint64>(MassDataType::MASS_SPECTRUM)); | |
| 170 | |||
| 171 | ✗ | msp_writer->append("TITLE"); | |
| 172 | ✗ | msp_writer->append(m_title); | |
| 173 | |||
| 174 | ✗ | msp_writer->append("TRACE_COLOR"); | |
| 175 | ✗ | msp_writer->append(m_colorByteArray); | |
| 176 | |||
| 177 | ✗ | msp_writer->append("X_LABEL"); | |
| 178 | ✗ | msp_writer->append("m/z"); | |
| 179 | |||
| 180 | ✗ | msp_writer->append("X_DATA"); | |
| 181 | ✗ | msp_writer->append(m_trace.xAsBase64Encoded()); | |
| 182 | |||
| 183 | ✗ | msp_writer->append("Y_LABEL"); | |
| 184 | ✗ | msp_writer->append("intensity"); | |
| 185 | |||
| 186 | ✗ | msp_writer->append("Y_DATA"); | |
| 187 | ✗ | msp_writer->append(m_trace.yAsBase64Encoded()); | |
| 188 | |||
| 189 | ✗ | msp_writer->endMap(); | |
| 190 | // Close the map now. | ||
| 191 | ✗ | } | |
| 192 | |||
| 193 | |||
| 194 | bool | ||
| 195 | ✗ | MassDataCborMassSpectrumHandler::readContext(QCborStreamReaderSPtr &reader_sp) | |
| 196 | { | ||
| 197 | // The format for this kind of CBOR pappso::Trace data is the following: | ||
| 198 | |||
| 199 | // The whole file is actually a map that contains the key/value | ||
| 200 | // pairs below. | ||
| 201 | |||
| 202 | // The text string values below are described in this way in the specif: | ||
| 203 | // Major type 3: a text string, specifically a string of Unicode characters | ||
| 204 | // that is encoded as UTF-8 (that is, not a QByteArray, but a QString). | ||
| 205 | |||
| 206 | // The containers, map, strings and byte arrays dot not need the reader to | ||
| 207 | // explicitely advance to next(). | ||
| 208 | |||
| 209 | // The simple value, like integers, do need that reader's next() call. | ||
| 210 | |||
| 211 | // So now, the MAP with the following key/value pairs: | ||
| 212 | |||
| 213 | // start_map | ||
| 214 | |||
| 215 | // "DATA_TYPE" / value (quint64) | ||
| 216 | // "TITLE" / value (text string) | ||
| 217 | // "X_LABEL" / value (text string) | ||
| 218 | // "Y_LABEL" / value (text string) | ||
| 219 | // | ||
| 220 | // "X_DATA" / value (base64 ByteArray) | ||
| 221 | // "Y_DATA" / value (base64 ByteArray) | ||
| 222 | |||
| 223 | // end_map | ||
| 224 | |||
| 225 | // These are needed to store the x and y data as two different byte arrays. | ||
| 226 | |||
| 227 | ✗ | while(reader_sp->lastError() == QCborError::NoError && reader_sp->hasNext()) | |
| 228 | { | ||
| 229 | ✗ | QCborStreamReader::Type type = reader_sp->type(); | |
| 230 | // qDebug() << "Type is:" << type; | ||
| 231 | |||
| 232 | ✗ | if(type == QCborStreamReader::UnsignedInteger) | |
| 233 | { | ||
| 234 | // In this format, the QCborStreamReader::UnsignedInteger datum is | ||
| 235 | // only got as the very first data bit in the file. This bit of | ||
| 236 | // information is a quint64 representing MassDataType::MASS_SPECTRUM. | ||
| 237 | |||
| 238 | // Now check that the read value actually corresponds to the expected | ||
| 239 | // mass data type for which this object is working! | ||
| 240 | |||
| 241 | ✗ | if(m_currentKey == "DATA_TYPE") | |
| 242 | { | ||
| 243 | // quint64 data_type = 0; | ||
| 244 | // data_type = reader_sp->toUnsignedInteger(); | ||
| 245 | // qDebug() << "The mass data type:" << data_type; | ||
| 246 | |||
| 247 | ✗ | if(static_cast<MassDataType>(reader_sp->toUnsignedInteger()) != | |
| 248 | MassDataType::MASS_SPECTRUM) | ||
| 249 | { | ||
| 250 | ✗ | qDebug() | |
| 251 | ✗ | << "The expected DATA_TYPE::MASS_SPECTRUM was not found."; | |
| 252 | ✗ | return false; | |
| 253 | } | ||
| 254 | |||
| 255 | ✗ | m_massDataType = MassDataType::MASS_SPECTRUM; | |
| 256 | |||
| 257 | ✗ | m_currentKey = QString(); | |
| 258 | } | ||
| 259 | |||
| 260 | // qDebug() << "At this point, check if it has next:" | ||
| 261 | //<< reader_sp->hasNext(); | ||
| 262 | |||
| 263 | // We had what we wanted, go to next. | ||
| 264 | ✗ | reader_sp->next(); | |
| 265 | } | ||
| 266 | ✗ | else if(type == QCborStreamReader::String) | |
| 267 | { | ||
| 268 | // Read a CBOR string, concatenating all | ||
| 269 | // the chunks into a single string. | ||
| 270 | ✗ | QString str; | |
| 271 | ✗ | auto chunk = reader_sp->readString(); | |
| 272 | ✗ | while(chunk.status == QCborStreamReader::Ok) | |
| 273 | { | ||
| 274 | ✗ | str += chunk.data; | |
| 275 | ✗ | chunk = reader_sp->readString(); | |
| 276 | } | ||
| 277 | |||
| 278 | ✗ | if(chunk.status == QCborStreamReader::Error) | |
| 279 | { | ||
| 280 | // handle error condition | ||
| 281 | ✗ | qDebug() << "There was an error reading string chunk."; | |
| 282 | ✗ | str.clear(); | |
| 283 | } | ||
| 284 | |||
| 285 | // qDebug() << "The string that was read:" << str; | ||
| 286 | |||
| 287 | // If the current key is empty, this string value is a new key or tag. | ||
| 288 | // Otherwise, it's a value. | ||
| 289 | |||
| 290 | ✗ | if(m_currentKey.isEmpty()) | |
| 291 | { | ||
| 292 | // qDebug() << "Setting m_currentKey:" << str; | ||
| 293 | ✗ | m_currentKey = str; | |
| 294 | } | ||
| 295 | else | ||
| 296 | { | ||
| 297 | // Depending on what we had already, we will set the proper member | ||
| 298 | // datum. | ||
| 299 | ✗ | if(m_currentKey == "TITLE") | |
| 300 | { | ||
| 301 | // qDebug() << "Setting m_title:" << str; | ||
| 302 | ✗ | m_title = str; | |
| 303 | } | ||
| 304 | |||
| 305 | ✗ | if(m_currentKey == "X_LABEL") | |
| 306 | { | ||
| 307 | // qDebug() << "Setting m_xLabel:" << str; | ||
| 308 | |||
| 309 | ✗ | m_xLabel = str; | |
| 310 | } | ||
| 311 | |||
| 312 | ✗ | if(m_currentKey == "Y_LABEL") | |
| 313 | { | ||
| 314 | // qDebug() << "Setting m_yLabel:" << str; | ||
| 315 | ✗ | m_yLabel = str; | |
| 316 | } | ||
| 317 | |||
| 318 | // At this point we can reset m_currentKey. | ||
| 319 | ✗ | m_currentKey = QString(); | |
| 320 | } | ||
| 321 | ✗ | } | |
| 322 | |||
| 323 | // The ByteArray data for X_DATA and Y_DATA. | ||
| 324 | // They are preceded by the keys "X_DATA" and "Y_DATA" respectively. | ||
| 325 | |||
| 326 | ✗ | else if(type == QCborStreamReader::ByteArray) | |
| 327 | { | ||
| 328 | // Read a byte array. That could be either the X_DATA or the Y_DATA. | ||
| 329 | |||
| 330 | ✗ | QByteArray array; | |
| 331 | |||
| 332 | ✗ | auto chunk = reader_sp->readByteArray(); | |
| 333 | |||
| 334 | ✗ | while(chunk.status == QCborStreamReader::Ok) | |
| 335 | { | ||
| 336 | ✗ | array.append(chunk.data); | |
| 337 | ✗ | chunk = reader_sp->readByteArray(); | |
| 338 | } | ||
| 339 | |||
| 340 | ✗ | if(m_currentKey == "X_DATA") | |
| 341 | { | ||
| 342 | ✗ | m_xBase64Data = array; | |
| 343 | } | ||
| 344 | ✗ | else if(m_currentKey == "Y_DATA") | |
| 345 | { | ||
| 346 | ✗ | m_yBase64Data = array; | |
| 347 | } | ||
| 348 | ✗ | else if(m_currentKey == "TRACE_COLOR") | |
| 349 | { | ||
| 350 | ✗ | m_colorByteArray = array; | |
| 351 | } | ||
| 352 | else | ||
| 353 | { | ||
| 354 | ✗ | qDebug() << "Error in the data read from file."; | |
| 355 | ✗ | return false; | |
| 356 | } | ||
| 357 | |||
| 358 | ✗ | m_currentKey = QString(); | |
| 359 | ✗ | } | |
| 360 | |||
| 361 | // The MAP has the following key/value pairs: | ||
| 362 | |||
| 363 | // start_map | ||
| 364 | |||
| 365 | // "TITLE" / value (text string) | ||
| 366 | // "X_LABEL" / value (text string) | ||
| 367 | // "Y_LABEL" / value (text string) | ||
| 368 | // | ||
| 369 | // "X_DATA" / value (base64 ByteArray) | ||
| 370 | // "Y_DATA" / value (base64 ByteArray) | ||
| 371 | |||
| 372 | // end_map | ||
| 373 | |||
| 374 | ✗ | else if(type == QCborStreamReader::Map) | |
| 375 | { | ||
| 376 | |||
| 377 | ✗ | reader_sp->enterContainer(); | |
| 378 | |||
| 379 | // Read elements until end of map is reached | ||
| 380 | ✗ | bool res = readContext(reader_sp); | |
| 381 | ✗ | if(res) | |
| 382 | ✗ | reader_sp->leaveContainer(); | |
| 383 | else | ||
| 384 | ✗ | return false; | |
| 385 | } | ||
| 386 | else | ||
| 387 | { | ||
| 388 | // Ignore all other types, go to the next element | ||
| 389 | ✗ | reader_sp->next(); | |
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | ✗ | if(reader_sp->lastError() != QCborError::NoError) | |
| 394 | ✗ | qDebug() << "There was an error: " << reader_sp->lastError() | |
| 395 | ✗ | << "Returning false."; | |
| 396 | |||
| 397 | // Return true if there were no errors | ||
| 398 | // qDebug() << "Returning: " << !reader_sp->lastError(); | ||
| 399 | |||
| 400 | ✗ | return !reader_sp->lastError(); | |
| 401 | } | ||
| 402 | |||
| 403 | |||
| 404 | bool | ||
| 405 | ✗ | MassDataCborMassSpectrumHandler::readByteArray(const QByteArray &byte_array) | |
| 406 | { | ||
| 407 | ✗ | msp_reader = std::make_shared<QCborStreamReader>(byte_array); | |
| 408 | |||
| 409 | ✗ | bool res = readContext(msp_reader); | |
| 410 | |||
| 411 | // qDebug() << "After finishing the read, m_title is:" << m_title | ||
| 412 | //<< "and mass data type is:" << static_cast<quint64>(m_massDataType); | ||
| 413 | |||
| 414 | // At this point we need to decode the arrays and with the data initialize the | ||
| 415 | // pappso::Trace. | ||
| 416 | |||
| 417 | ✗ | QByteArray x_array; | |
| 418 | ✗ | QByteArray y_array; | |
| 419 | |||
| 420 | QByteArray::FromBase64Result decoding_result = QByteArray::fromBase64Encoding( | ||
| 421 | ✗ | m_xBase64Data, QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals); | |
| 422 | |||
| 423 | ✗ | if(decoding_result.decodingStatus == QByteArray::Base64DecodingStatus::Ok) | |
| 424 | ✗ | x_array = decoding_result.decoded; | |
| 425 | else | ||
| 426 | { | ||
| 427 | ✗ | qDebug() << "Failed to decode the " << m_xLabel << "data"; | |
| 428 | ✗ | return false; | |
| 429 | } | ||
| 430 | |||
| 431 | ✗ | decoding_result = QByteArray::fromBase64Encoding( | |
| 432 | ✗ | m_yBase64Data, QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals); | |
| 433 | |||
| 434 | ✗ | if(decoding_result.decodingStatus == QByteArray::Base64DecodingStatus::Ok) | |
| 435 | ✗ | y_array = decoding_result.decoded; | |
| 436 | else | ||
| 437 | { | ||
| 438 | ✗ | qDebug() << "Failed to decode the " << m_yLabel << "data"; | |
| 439 | ✗ | return false; | |
| 440 | } | ||
| 441 | |||
| 442 | ✗ | m_trace.clear(); | |
| 443 | |||
| 444 | ✗ | m_trace.initialize(QString(x_array), QString(y_array)); | |
| 445 | |||
| 446 | ✗ | return res; | |
| 447 | ✗ | } | |
| 448 | |||
| 449 | |||
| 450 | bool | ||
| 451 | ✗ | MassDataCborMassSpectrumHandler::readFile(const QString &input_file_name) | |
| 452 | { | ||
| 453 | // The format for this kind of CBOR pappso::Trace data is the following: | ||
| 454 | |||
| 455 | // First the quint64 that represents MassDataType. In our specific case, that | ||
| 456 | // must be MassDataType::MASS_SPECTRUM. | ||
| 457 | |||
| 458 | // Then there is the title of data, which is according to the specification: | ||
| 459 | // | ||
| 460 | // Major type 3: a text string, specifically a string of Unicode characters | ||
| 461 | // that is encoded as UTF-8 (that is, not a QByteArray, but a QString). | ||
| 462 | |||
| 463 | // Then there is a MAP with the following key/value pairs: | ||
| 464 | |||
| 465 | // start_map | ||
| 466 | |||
| 467 | // "X_LABEL" / value (text string) | ||
| 468 | // "Y_LABEL" / value (text string) | ||
| 469 | // | ||
| 470 | // "X_DATA" / value (base64 ByteArray) | ||
| 471 | // "Y_DATA" / value (base64 ByteArray) | ||
| 472 | |||
| 473 | // end_map | ||
| 474 | |||
| 475 | |||
| 476 | ✗ | QString local_file_name = input_file_name; | |
| 477 | |||
| 478 | ✗ | if(local_file_name.isEmpty()) | |
| 479 | ✗ | local_file_name = m_inputFileName; | |
| 480 | |||
| 481 | ✗ | QFileInfo file_info(local_file_name); | |
| 482 | |||
| 483 | ✗ | if(!file_info.exists()) | |
| 484 | { | ||
| 485 | ✗ | qDebug() << "File not found."; | |
| 486 | ✗ | return false; | |
| 487 | } | ||
| 488 | |||
| 489 | ✗ | QFile file(local_file_name); | |
| 490 | |||
| 491 | ✗ | bool res = file.open(QIODevice::ReadOnly); | |
| 492 | |||
| 493 | ✗ | if(!res) | |
| 494 | { | ||
| 495 | ✗ | qDebug() << "Failed to open the file for read."; | |
| 496 | ✗ | return false; | |
| 497 | } | ||
| 498 | |||
| 499 | // qDebug() << "Now starting the CBOR data read."; | ||
| 500 | |||
| 501 | ✗ | msp_reader = std::make_shared<QCborStreamReader>(&file); | |
| 502 | |||
| 503 | ✗ | res = readContext(msp_reader); | |
| 504 | |||
| 505 | ✗ | file.close(); | |
| 506 | |||
| 507 | // qDebug() << "After finishing the read, m_title is:" << m_title | ||
| 508 | //<< "and mass data type is:" << static_cast<quint64>(m_massDataType); | ||
| 509 | |||
| 510 | // At this point we need to decode the arrays and with the data initialize the | ||
| 511 | // pappso::Trace. | ||
| 512 | |||
| 513 | ✗ | QByteArray x_array; | |
| 514 | ✗ | QByteArray y_array; | |
| 515 | |||
| 516 | QByteArray::FromBase64Result decoding_result = QByteArray::fromBase64Encoding( | ||
| 517 | ✗ | m_xBase64Data, QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals); | |
| 518 | |||
| 519 | ✗ | if(decoding_result.decodingStatus == QByteArray::Base64DecodingStatus::Ok) | |
| 520 | ✗ | x_array = decoding_result.decoded; | |
| 521 | else | ||
| 522 | { | ||
| 523 | ✗ | qDebug() << "Failed to decode the " << m_xLabel << "data"; | |
| 524 | ✗ | return false; | |
| 525 | } | ||
| 526 | |||
| 527 | ✗ | decoding_result = QByteArray::fromBase64Encoding( | |
| 528 | ✗ | m_yBase64Data, QByteArray::Base64Encoding | QByteArray::OmitTrailingEquals); | |
| 529 | |||
| 530 | ✗ | if(decoding_result.decodingStatus == QByteArray::Base64DecodingStatus::Ok) | |
| 531 | ✗ | y_array = decoding_result.decoded; | |
| 532 | else | ||
| 533 | { | ||
| 534 | ✗ | qDebug() << "Failed to decode the " << m_yLabel << "data"; | |
| 535 | ✗ | return false; | |
| 536 | } | ||
| 537 | |||
| 538 | ✗ | m_trace.clear(); | |
| 539 | |||
| 540 | ✗ | m_trace.initialize(QString(x_array), QString(y_array)); | |
| 541 | |||
| 542 | ✗ | return res; | |
| 543 | ✗ | } | |
| 544 | |||
| 545 | |||
| 546 | void | ||
| 547 | ✗ | MassDataCborMassSpectrumHandler::setXLabel(const QString &label) | |
| 548 | { | ||
| 549 | ✗ | m_xLabel = label; | |
| 550 | ✗ | } | |
| 551 | |||
| 552 | |||
| 553 | QString | ||
| 554 | ✗ | MassDataCborMassSpectrumHandler::getXLabel() const | |
| 555 | { | ||
| 556 | ✗ | return m_xLabel; | |
| 557 | } | ||
| 558 | |||
| 559 | |||
| 560 | void | ||
| 561 | ✗ | MassDataCborMassSpectrumHandler::setYLabel(const QString &label) | |
| 562 | { | ||
| 563 | ✗ | m_yLabel = label; | |
| 564 | ✗ | } | |
| 565 | |||
| 566 | |||
| 567 | QString | ||
| 568 | ✗ | MassDataCborMassSpectrumHandler::getYLabel() const | |
| 569 | { | ||
| 570 | ✗ | return m_yLabel; | |
| 571 | } | ||
| 572 | |||
| 573 | void | ||
| 574 | ✗ | MassDataCborMassSpectrumHandler::setTrace(const pappso::Trace &trace) | |
| 575 | { | ||
| 576 | ✗ | m_trace = trace; | |
| 577 | ✗ | } | |
| 578 | |||
| 579 | |||
| 580 | pappso::Trace | ||
| 581 | ✗ | MassDataCborMassSpectrumHandler::getTrace() const | |
| 582 | { | ||
| 583 | ✗ | return m_trace; | |
| 584 | }; | ||
| 585 | |||
| 586 | |||
| 587 | void | ||
| 588 | ✗ | MassDataCborMassSpectrumHandler::clearTrace() | |
| 589 | { | ||
| 590 | ✗ | m_trace.clear(); | |
| 591 | ✗ | } | |
| 592 | |||
| 593 | |||
| 594 | void | ||
| 595 | ✗ | MassDataCborMassSpectrumHandler::setTraceColor( | |
| 596 | const QByteArray &color_byte_array) | ||
| 597 | { | ||
| 598 | ✗ | m_colorByteArray = color_byte_array; | |
| 599 | ✗ | } | |
| 600 | |||
| 601 | |||
| 602 | QByteArray | ||
| 603 | ✗ | MassDataCborMassSpectrumHandler::getTraceColor() const | |
| 604 | { | ||
| 605 | ✗ | return m_colorByteArray; | |
| 606 | } | ||
| 607 | |||
| 608 | |||
| 609 | } // namespace libXpertMass | ||
| 610 | |||
| 611 | |||
| 612 | } // namespace MsXpS | ||
| 613 | |||
| 614 |