36#include <QJsonDocument>
52static const QByteArray MNX_MAGIC = QByteArrayLiteral(
"MNX1");
60 const QFileInfo fi(path);
61 const QString suffix = fi.suffix().toLower();
63 if(suffix == QLatin1String(
"mna")) {
64 return readJson(path);
65 }
else if(suffix == QLatin1String(
"mnx")) {
66 return readCbor(path);
69 qWarning() <<
"[MnaIO::read] Unknown extension:" << suffix;
77 const QFileInfo fi(path);
78 const QString suffix = fi.suffix().toLower();
80 if(suffix == QLatin1String(
"mna")) {
81 return writeJson(project, path);
82 }
else if(suffix == QLatin1String(
"mnx")) {
83 return writeCbor(project, path);
86 qWarning() <<
"[MnaIO::write] Unknown extension:" << suffix;
95 if(!file.open(QIODevice::ReadOnly)) {
96 qWarning() <<
"[MnaIO::readJson] Cannot open file:" << path;
100 const QByteArray data = file.readAll();
103 QJsonParseError parseError;
104 const QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
105 if(parseError.error != QJsonParseError::NoError) {
106 qWarning() <<
"[MnaIO::readJson] Parse error:" << parseError.errorString();
110 const QJsonObject root = doc.object();
113 const QString fileVersion = root[QLatin1String(
"mna_version")].toString();
114 const int fileMajor = fileVersion.section(QLatin1Char(
'.'), 0, 0).toInt();
116 if(fileMajor != currentMajor) {
117 qWarning() <<
"[MnaIO::readJson] Incompatible major version:" << fileVersion
118 <<
"(expected major" << currentMajor <<
")";
127bool MnaIO::writeJson(
const MnaProject& project,
const QString& path)
130 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
131 qWarning() <<
"[MnaIO::writeJson] Cannot open file for writing:" << path;
135 const QJsonDocument doc(project.
toJson());
136 const QByteArray data = doc.toJson(QJsonDocument::Indented);
137 const qint64 written = file.write(data);
140 return (written == data.size());
145MnaProject MnaIO::readCbor(
const QString& path)
148 if(!file.open(QIODevice::ReadOnly)) {
149 qWarning() <<
"[MnaIO::readCbor] Cannot open file:" << path;
154 const QByteArray magic = file.read(MNX_MAGIC.size());
155 if(magic != MNX_MAGIC) {
156 qWarning() <<
"[MnaIO::readCbor] Invalid magic header in:" << path;
161 const QByteArray cborData = file.readAll();
164 const QCborValue cborVal = QCborValue::fromCbor(cborData);
165 if(!cborVal.isMap()) {
166 qWarning() <<
"[MnaIO::readCbor] Root CBOR value is not a map";
170 const QCborMap root = cborVal.toMap();
173 const QString fileVersion = root[QLatin1String(
"mna_version")].toString();
174 const int fileMajor = fileVersion.section(QLatin1Char(
'.'), 0, 0).toInt();
176 if(fileMajor != currentMajor) {
177 qWarning() <<
"[MnaIO::readCbor] Incompatible major version:" << fileVersion
178 <<
"(expected major" << currentMajor <<
")";
187bool MnaIO::writeCbor(
const MnaProject& project,
const QString& path)
190 if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
191 qWarning() <<
"[MnaIO::writeCbor] Cannot open file for writing:" << path;
196 if(file.write(MNX_MAGIC) != MNX_MAGIC.size()) {
197 qWarning() <<
"[MnaIO::writeCbor] Failed to write magic header";
202 const QCborValue cborVal(project.
toCbor());
203 const QByteArray cborData = cborVal.toCbor();
204 const qint64 written = file.write(cborData);
207 return (written == cborData.size());
Reader and writer for MNA project containers — .mna (JSON, human-editable) and .mnx (CBOR,...
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