47#include <QJsonDocument>
63static const QByteArray MNX_MAGIC = QByteArrayLiteral(
"MNX1");
71 const QFileInfo fi(path);
72 const QString suffix = fi.suffix().toLower();
74 if(suffix == QLatin1String(
"mna")) {
75 return readJson(path);
76 }
else if(suffix == QLatin1String(
"mnx")) {
77 return readCbor(path);
80 qWarning() <<
"[MnaIO::read] Unknown extension:" << suffix;
88 const QFileInfo fi(path);
89 const QString suffix = fi.suffix().toLower();
91 if(suffix == QLatin1String(
"mna")) {
92 return writeJson(project, path);
93 }
else if(suffix == QLatin1String(
"mnx")) {
94 return writeCbor(project, path);
97 qWarning() <<
"[MnaIO::write] Unknown extension:" << suffix;
103MnaProject MnaIO::readJson(
const QString& path)
106 if(!file.open(QIODevice::ReadOnly)) {
107 qWarning() <<
"[MnaIO::readJson] Cannot open file:" << path;
111 const QByteArray data = file.readAll();
114 QJsonParseError parseError;
115 const QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
116 if(parseError.error != QJsonParseError::NoError) {
117 qWarning() <<
"[MnaIO::readJson] Parse error:" << parseError.errorString();
121 const QJsonObject root = doc.object();
124 const QString fileVersion = root[QLatin1String(
"mna_version")].toString();
125 const int fileMajor = fileVersion.section(QLatin1Char(
'.'), 0, 0).toInt();
127 if(fileMajor != currentMajor) {
128 qWarning() <<
"[MnaIO::readJson] Incompatible major version:" << fileVersion
129 <<
"(expected major" << currentMajor <<
")";
138bool MnaIO::writeJson(
const MnaProject& project,
const QString& path)
141 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
142 qWarning() <<
"[MnaIO::writeJson] Cannot open file for writing:" << path;
146 const QJsonDocument doc(project.
toJson());
147 const QByteArray data = doc.toJson(QJsonDocument::Indented);
148 const qint64 written = file.write(data);
151 return (written == data.size());
156MnaProject MnaIO::readCbor(
const QString& path)
159 if(!file.open(QIODevice::ReadOnly)) {
160 qWarning() <<
"[MnaIO::readCbor] Cannot open file:" << path;
165 const QByteArray magic = file.read(MNX_MAGIC.size());
166 if(magic != MNX_MAGIC) {
167 qWarning() <<
"[MnaIO::readCbor] Invalid magic header in:" << path;
172 const QByteArray cborData = file.readAll();
175 const QCborValue cborVal = QCborValue::fromCbor(cborData);
176 if(!cborVal.isMap()) {
177 qWarning() <<
"[MnaIO::readCbor] Root CBOR value is not a map";
181 const QCborMap root = cborVal.toMap();
184 const QString fileVersion = root[QLatin1String(
"mna_version")].toString();
185 const int fileMajor = fileVersion.section(QLatin1Char(
'.'), 0, 0).toInt();
187 if(fileMajor != currentMajor) {
188 qWarning() <<
"[MnaIO::readCbor] Incompatible major version:" << fileVersion
189 <<
"(expected major" << currentMajor <<
")";
198bool MnaIO::writeCbor(
const MnaProject& project,
const QString& path)
201 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
202 qWarning() <<
"[MnaIO::writeCbor] Cannot open file for writing:" << path;
207 if(file.write(MNX_MAGIC) != MNX_MAGIC.size()) {
208 qWarning() <<
"[MnaIO::writeCbor] Failed to write magic header";
213 const QCborValue cborVal(project.
toCbor());
214 const QByteArray cborData = cborVal.toCbor();
215 const qint64 written = file.write(cborData);
218 return (written == cborData.size());
MNE Analysis Container Format (mna/mnx).
static bool write(const MnaProject &project, const QString &path)
static MnaProject read(const QString &path)
QJsonObject toJson() const
static MnaProject fromJson(const QJsonObject &json)
static MnaProject fromCbor(const QCborMap &cbor)
static constexpr const char * CURRENT_SCHEMA_VERSION