1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Model/Sim/InstrumentXML.cpp
//! @brief Implements class InstrumentXML.
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "GUI/Model/Sim/InstrumentXML.h"
#include "Base/Util/Assert.h"
#include "GUI/Model/Sim/InstrumentCatalog.h"
#include "GUI/Model/Sim/InstrumentItems.h"
#include "GUI/Model/Util/Path.h"
#include "GUI/Model/Util/UtilXML.h"
#include <QFile>
namespace {
const QString XML_ROOT_TAG = "BornAgain_Instrument";
} // namespace
void InstrumentXML::save(const QString& fname, const InstrumentItem* t)
{
QFile file(fname);
if (!file.open(QFile::ReadWrite | QIODevice::Truncate | QFile::Text))
throw std::runtime_error("Cannot open instrument file for writing");
QXmlStreamWriter w(&file);
w.setAutoFormatting(true);
w.writeStartDocument();
w.writeStartElement(XML_ROOT_TAG);
w.writeAttribute(XML::Attrib::BA_Version, GUI::Path::getBornAgainVersionString());
const uint typeIndex = static_cast<uint>(InstrumentCatalog::type(t));
XML::writeAttribute(&w, XML::Attrib::type, typeIndex);
// The next line allows to see the name of item type in XML. Can be skipped in reading.
XML::writeAttribute(&w, XML::Attrib::name,
InstrumentCatalog::uiInfo(InstrumentCatalog::type(t)).menuEntry);
t->writeTo(&w);
w.writeEndElement();
w.writeEndDocument();
file.close();
}
InstrumentItem* InstrumentXML::load(const QString& fname)
{
InstrumentItem* t = nullptr;
QFile file(fname);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
throw std::runtime_error("Cannot open instrument file for reading");
QXmlStreamReader r(&file);
if (r.atEnd())
throw std::runtime_error("Empty instrument file?");
r.readNext();
if (!r.isStartDocument())
throw std::runtime_error("Missing StartDocument in instrument file");
r.readNext();
if (!r.isStartElement())
throw std::runtime_error("Missing start element in instrument file");
if (r.name() != XML_ROOT_TAG)
throw std::runtime_error("Missing root tag in instrument file, found "
+ r.name().toString().toStdString());
const QString found_version = r.attributes().value(XML::Attrib::BA_Version).toString();
if (found_version.toDouble() < XML::minimal_supported_version.toDouble())
throw std::runtime_error("Unsupported version of instrument element, must be at least "
+ XML::minimal_supported_version.toStdString());
const uint typeIndex = XML::readUInt(&r, XML::Attrib::type);
const auto type = static_cast<typename InstrumentCatalog::Type>(typeIndex);
t = InstrumentCatalog::create(type);
ASSERT(t);
t->readFrom(&r);
if (r.hasError())
throw std::runtime_error(QString("Error in instrument file, line %1, column %2: %3")
.arg(r.lineNumber())
.arg(r.columnNumber())
.arg(r.errorString())
.toStdString());
file.close();
return t;
}
|