Skip to content

Commit

Permalink
feat: write cdf as json and settings as json (#123)
Browse files Browse the repository at this point in the history
* feat: write cdf as json and settings as json

* fix: runtime error when saving as json

* refactor: use SFAINE instead of constexpr

* fix: compiler error on non-msvc compiler
  • Loading branch information
alphagocc authored May 30, 2021
1 parent 396957d commit 79ef477
Show file tree
Hide file tree
Showing 12 changed files with 248 additions and 55 deletions.
2 changes: 1 addition & 1 deletion makespec/BUILDVERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
144
149
31 changes: 27 additions & 4 deletions src/base/LemonConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,42 @@ namespace Lemon::base::config {
QJsonArray _compilerList = json["compilerList"].toArray();
compilerList.clear();
compilerList.reserve(_compilerList.size());
for (int compilerIndex = 0; compilerIndex < _compilerList.size(); ++compilerIndex) {
QJsonObject compilerObject = _compilerList[compilerIndex].toObject();
for (int i = 0; i < _compilerList.size(); ++i) {
QJsonObject compilerObject = _compilerList[i].toObject();
Compiler *compiler = new Compiler;
if (compiler->read(compilerObject) == -1)
return -1;
compilerList.append(compiler);
}
}
} else
return -1;
return 0;
}

void LemonConfigJudge::write(QJsonObject &json) const {
// TODO: Write Config
WRITE_JSON(json, defaultFullScore);
WRITE_JSON(json, defaultTimeLimit);
WRITE_JSON(json, defaultMemoryLimit);
WRITE_JSON(json, compileTimeLimit);
WRITE_JSON(json, specialJudgeTimeLimit);
WRITE_JSON(json, fileSizeLimit);
WRITE_JSON(json, rejudgeTimes);

WRITE_JSON(json, defaultInputFileExtension);
WRITE_JSON(json, defaultOutputFileExtension);
WRITE_JSON(json, diffPath);

WRITE_JSON(json, inputFileExtensions);
WRITE_JSON(json, outputFileExtensions);
WRITE_JSON(json, recentContest);

QJsonArray compilerList;
for (const auto compiler : this->compilerList) {
QJsonObject obj;
compiler->write(obj);
compilerList.append(obj);
}
WRITE_JSON(json, compilerList);
}

} // namespace Lemon::base::config
85 changes: 60 additions & 25 deletions src/base/LemonUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,102 +10,137 @@
#include <QDir>
#include <QJsonArray>
#include <QJsonObject>

#include <type_traits>
namespace Lemon::detail {
inline int JsonReadHelper(QString &val, const QJsonValue &jval) {
inline int jsonReadHelper(QString &val, const QJsonValue &jval) {
if (jval.isString()) {
val = jval.toString();
return 0;
} else
return -1;
}
inline int JsonReadHelper(int &val, const QJsonValue &jval) {
inline int jsonReadHelper(int &val, const QJsonValue &jval) {
if (jval.isDouble()) {
val = jval.toInt();
return 0;
} else
return -1;
}
inline int JsonReadHelper(bool &val, const QJsonValue &jval) {
inline int jsonReadHelper(bool &val, const QJsonValue &jval) {
if (jval.isBool()) {
val = jval.toBool();
return 0;
} else
return -1;
}
inline int JsonReadHelper(double &val, const QJsonValue &jval) {
inline int jsonReadHelper(double &val, const QJsonValue &jval) {
if (jval.isDouble()) {
val = jval.toDouble();
return 0;
} else
return -1;
}
inline int JsonReadHelper(QJsonObject &val, const QJsonValue &jval) {
inline int jsonReadHelper(QJsonObject &val, const QJsonValue &jval) {
if (jval.isObject()) {
val = jval.toObject();
return 0;
} else
return -1;
}
inline int JsonReadHelper(QJsonArray &val, const QJsonValue &jval) {
inline int jsonReadHelper(QJsonArray &val, const QJsonValue &jval) {
if (jval.isArray()) {
val = jval.toArray();
QJsonArray arr;
return 0;
} else
return -1;
}
inline int JsonReadHelper(ResultState &val, const QJsonValue &jval) {
inline int jsonReadHelper(ResultState &val, const QJsonValue &jval) {
int x;
if (JsonReadHelper(x, jval) == -1)
if (jsonReadHelper(x, jval) == -1)
return -1;
val = ResultState(x);
val = static_cast<ResultState>(x);
return 0;
}
inline int JsonReadHelper(CompileState &val, const QJsonValue &jval) {
inline int jsonReadHelper(CompileState &val, const QJsonValue &jval) {
int x;
if (JsonReadHelper(x, jval) == -1)
if (jsonReadHelper(x, jval) == -1)
return -1;
val = CompileState(x);
val = static_cast<CompileState>(x);
return 0;
}
template <typename T> int JsonReadHelper(QList<T> &val, const QJsonValue &jval) {
template <typename T> int jsonReadHelper(QList<T> &val, const QJsonValue &jval) {
QJsonArray arr;
return JsonReadHelper(arr, jval) == -1 || JsonReadHelper(val, arr) == -1 ? -1 : 0;
return jsonReadHelper(arr, jval) == -1 || jsonReadHelper(val, arr) == -1 ? -1 : 0;
}
inline int JsonReadHelper(QStringList &val, const QJsonArray &jval) {
inline int jsonReadHelper(QStringList &val, const QJsonArray &jval) {
QList<QString> s;
if (JsonReadHelper(s, jval) == -1)
if (jsonReadHelper(s, jval) == -1)
return -1;
val = s;
return 0;
}
template <typename T> int JsonReadHelper(QList<T> &val, const QJsonArray &jval) {
template <typename T> int jsonReadHelper(QList<T> &val, const QJsonArray &jval) {
val.clear();
for (auto i : jval) {
T x;
if (JsonReadHelper(x, i) == -1)
if (jsonReadHelper(x, i) == -1)
return -1;
val.append(x);
}
return 0;
}
template <typename T> int JsonReadHelper(T &val, const QString &name, const QJsonObject &json);
template <typename T> int JsonReadHelper(T &val, const QString &name, const QJsonObject &json) {
template <typename T> int jsonReadHelper(T &val, const QString &name, const QJsonObject &json) {
if (json.contains(name))
return JsonReadHelper(val, json[name]);
return jsonReadHelper(val, json[name]);
else
return -1;
}

template <typename T>
std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T> ||
std::is_same_v<std::remove_cv_t<T>, QString> ||
std::is_same_v<std::remove_cv_t<T>, QJsonArray> ||
std::is_same_v<std::remove_cv_t<T>, QJsonValue> ||
std::is_same_v<std::remove_cv_t<T>, QJsonObject>,
void>
jsonWriteHelper(const T &val, QJsonValue &jval) {
jval = val;
}
template <typename T>
std::enable_if_t<std::is_enum_v<T>, void> jsonWriteHelper(const T &val, QJsonValue &jval) {
jval = static_cast<int>(val);
}
template <typename T> void jsonWriteHelper(const QList<T> &val, QJsonValue &jval) {
QJsonArray arr;
for (const T &i : val) {
QJsonValue x;
jsonWriteHelper(i, x);
arr.append(x);
}
jval = arr;
}
inline void jsonWriteHelper(const QStringList &val, QJsonValue &jval) {
QList<QString> s = val;
jsonWriteHelper(s, jval);
}
template <typename T> void jsonWriteHelper(const T &val, const QString &name, QJsonObject &json) {
QJsonValue jval;
jsonWriteHelper(val, jval);
json[name] = jval;
}
} // namespace Lemon::detail
#define WRITE_JSON(json, ___x) json[#___x] = ___x;
#define WRITE_JSON_STRLIST(json, ___x) json[#___x] = ___x.join(QLatin1Char(';'));

namespace Lemon {
template <typename T> int readJson(T &x, const QString &name, const QJsonObject &json) {
return detail::JsonReadHelper(x, name, json);
return detail::jsonReadHelper(x, name, json);
}
template <typename T> void writeJson(const T &x, const QString &name, QJsonObject &json) {
detail::jsonWriteHelper(x, name, json);
}
} // namespace Lemon
#define READ_JSON(json, x) Lemon::readJson(x, #x, json)
#define WRITE_JSON(json, x) Lemon::writeJson(x, #x, json)
namespace Lemon::common {

QStringList GetFileList(const QDir &dir);
Expand Down
42 changes: 20 additions & 22 deletions src/base/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,14 @@ int Compiler::read(const QJsonObject &json) {
READ_JSON(json, compilerArguments);
READ_JSON(json, interpreterArguments);

QStringList _environment;
if (json.contains("environment") && json["environment"].isString()) {
_environment = json["environment"].toString().split(QLatin1Char(';'), Qt::SkipEmptyParts);
}
QStringList environment;
READ_JSON(json, environment);

for (auto &i : _environment) {
for (auto &i : environment) {
int tmp = i.indexOf('=');
QString variable = i.mid(0, tmp);
QString value = i.mid(tmp + 1);
environment.insert(variable, value);
this->environment.insert(variable, value);
}

READ_JSON(json, timeLimitRatio);
Expand All @@ -150,20 +148,20 @@ int Compiler::read(const QJsonObject &json) {
}

void Compiler::write(QJsonObject &json) const {
WRITE_JSON(json, compilerType)
WRITE_JSON(json, compilerName)
WRITE_JSON(json, compilerLocation)
WRITE_JSON(json, interpreterLocation)

WRITE_JSON_STRLIST(json, sourceExtensions)
WRITE_JSON_STRLIST(json, bytecodeExtensions)
WRITE_JSON_STRLIST(json, configurationNames)
WRITE_JSON_STRLIST(json, compilerArguments)
WRITE_JSON_STRLIST(json, interpreterArguments)

WRITE_JSON_STRLIST(json, environment.toStringList())

WRITE_JSON(json, timeLimitRatio) // double
WRITE_JSON(json, memoryLimitRatio) // double
WRITE_JSON(json, disableMemoryLimitCheck) // bool
WRITE_JSON(json, compilerType);
WRITE_JSON(json, compilerName);
WRITE_JSON(json, compilerLocation);
WRITE_JSON(json, interpreterLocation);

WRITE_JSON(json, sourceExtensions);
WRITE_JSON(json, bytecodeExtensions);
WRITE_JSON(json, configurationNames);
WRITE_JSON(json, compilerArguments);
WRITE_JSON(json, interpreterArguments);

WRITE_JSON(json, environment.toStringList());

WRITE_JSON(json, timeLimitRatio); // double
WRITE_JSON(json, memoryLimitRatio); // double
WRITE_JSON(json, disableMemoryLimitCheck); // bool
}
23 changes: 23 additions & 0 deletions src/core/contest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,29 @@ void Contest::writeToStream(QDataStream &out) {
i->writeToStream(out);
}
}
void Contest::writeToJson(QJsonObject &out) {
WRITE_JSON(out, contestTitle);

QJsonArray tasks;

for (const auto &i : taskList) {
QJsonObject obj;
i->writeToJson(obj);
tasks.append(obj);
}

WRITE_JSON(out, tasks);

QJsonArray contestants;

for (const auto &i : contestantList) {
QJsonObject obj;
i->writeToJson(out);
contestants.append(obj);
}

WRITE_JSON(out, contestants);
}
int Contest::readFromJson(const QJsonObject &in) {
READ_JSON(in, contestTitle);

Expand Down
1 change: 1 addition & 0 deletions src/core/contest.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Contest : public QObject {
void refreshContestantList();
void deleteContestant(const QString &);
void writeToStream(QDataStream &);
void writeToJson(QJsonObject &);
void readFromStream(QDataStream &);
int readFromJson(const QJsonObject &);

Expand Down
21 changes: 20 additions & 1 deletion src/core/contestant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,26 @@ auto Contestant::getTotalUsedTime() const -> int {

return total;
}

int Contestant::writeToJson(QJsonObject &out) {
WRITE_JSON(out, contestantName);
WRITE_JSON(out, checkJudged);
WRITE_JSON(out, sourceFile);
WRITE_JSON(out, compileMesaage);
WRITE_JSON(out, inputFiles);
WRITE_JSON(out, message);
WRITE_JSON(out, score);
WRITE_JSON(out, timeUsed);
WRITE_JSON(out, memoryUsed);
int judgingTime_date = judgingTime.date().toJulianDay();
int judgingTime_time = judgingTime.time().msecsSinceStartOfDay();
int judgingTime_timespec = judgingTime.timeSpec();
WRITE_JSON(out, judgingTime_date);
WRITE_JSON(out, judgingTime_time);
WRITE_JSON(out, judgingTime_timespec);
WRITE_JSON(out, compileState);
WRITE_JSON(out, result);
return 0;
}
void Contestant::writeToStream(QDataStream &out) {
out << contestantName;
out << checkJudged;
Expand Down
1 change: 1 addition & 0 deletions src/core/contestant.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Contestant : public QObject {
void setMemoryUsed(int, const QList<QList<int>> &);
void setJudgingTime(QDateTime);

int writeToJson(QJsonObject &);
void writeToStream(QDataStream &);
int readFromJson(const QJsonObject &);
void readFromStream(QDataStream &);
Expand Down
Loading

0 comments on commit 79ef477

Please sign in to comment.