##// END OF EJS Templates
Add impletation for displaying data that are already in cache when...
Add impletation for displaying data that are already in cache when acquisition is requested

File last commit:

r412:e1f4801c4363
r573:575eda7156d0
Show More
AmdaParser.cpp
125 lines | 4.2 KiB | text/x-c | CppLexer
#include "AmdaParser.h"
#include "AmdaDefs.h"
#include <DataSource/DataSourceItem.h>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
Q_LOGGING_CATEGORY(LOG_AmdaParser, "AmdaParser")
namespace {
/// Returns the correct item type according to the key passed in parameter
DataSourceItemType itemType(const QString &key) noexcept
{
if (key == AMDA_PRODUCT_KEY) {
return DataSourceItemType::PRODUCT;
}
else if (key == AMDA_COMPONENT_KEY) {
return DataSourceItemType::COMPONENT;
}
else {
return DataSourceItemType::NODE;
}
}
/**
* Processes an entry of the JSON file to populate/create data source items
* @param jsonKey the entry's key
* @param jsonValue the entry's value
* @param item the current item for which the entry processing will be applied
* @param appendData flag indicating that the entry is part of an array. In the case of an array of
* values, each value will be concatenated to the others (rather than replacing the others)
*/
void parseEntry(const QString &jsonKey, const QJsonValue &jsonValue, DataSourceItem &item,
bool isArrayEntry = false)
{
if (jsonValue.isObject()) {
// Case of an object:
// - a new data source item is created and
// - parsing is called recursively to process the new item
// - the new item is then added as a child of the former item
auto object = jsonValue.toObject();
auto newItem = std::make_unique<DataSourceItem>(itemType(jsonKey));
for (auto it = object.constBegin(), end = object.constEnd(); it != end; ++it) {
parseEntry(it.key(), it.value(), *newItem);
}
item.appendChild(std::move(newItem));
}
else if (jsonValue.isArray()) {
// Case of an array: the item is populated with the arrays' content
auto object = jsonValue.toArray();
for (auto it = object.constBegin(), end = object.constEnd(); it != end; ++it) {
parseEntry(jsonKey, *it, item, true);
}
}
else {
// Case of a simple value: we add a data to the item. If the simple value is a part of an
// array, it is concatenated to the values already existing for this key
item.setData(jsonKey, jsonValue.toVariant(), isArrayEntry);
}
}
} // namespace
std::unique_ptr<DataSourceItem> AmdaParser::readJson(const QString &filePath) noexcept
{
QFile jsonFile{filePath};
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCCritical(LOG_AmdaParser())
<< QObject::tr("Can't retrieve data source tree from file %1: %2")
.arg(filePath, jsonFile.errorString());
return nullptr;
}
auto json = jsonFile.readAll();
auto jsonDocument = QJsonDocument::fromJson(json);
// Check preconditions for parsing
if (!jsonDocument.isObject()) {
qCCritical(LOG_AmdaParser())
<< QObject::tr(
"Can't retrieve data source tree from file %1: the file is malformed (there is "
"not one and only one root object)")
.arg(filePath);
return nullptr;
}
auto jsonDocumentObject = jsonDocument.object();
if (!jsonDocumentObject.contains(AMDA_ROOT_KEY)) {
qCCritical(LOG_AmdaParser())
<< QObject::tr(
"Can't retrieve data source tree from file %1: the file is malformed (the key "
"for the root element was not found (%2))")
.arg(filePath, AMDA_ROOT_KEY);
return nullptr;
}
auto rootValue = jsonDocumentObject.value(AMDA_ROOT_KEY);
if (!rootValue.isObject()) {
qCCritical(LOG_AmdaParser())
<< QObject::tr(
"Can't retrieve data source tree from file %1: the file is malformed (the root "
"element is of the wrong type)")
.arg(filePath);
return nullptr;
}
// Makes the parsing
auto rootObject = rootValue.toObject();
auto rootItem = std::make_unique<DataSourceItem>(DataSourceItemType::NODE);
for (auto it = rootObject.constBegin(), end = rootObject.constEnd(); it != end; ++it) {
parseEntry(it.key(), it.value(), *rootItem);
}
return rootItem;
}