-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsonfile.cpp
More file actions
147 lines (106 loc) · 4.42 KB
/
jsonfile.cpp
File metadata and controls
147 lines (106 loc) · 4.42 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <QFile>
#include <QJsonObject>
#include "jsonfile.hpp"
using namespace Headway;
JsonFile::JsonFile(const QString& filePath)
{
QFile fileHandle(filePath);
if (!fileHandle.open(QIODevice::ReadOnly | QIODevice::Text))
{
throw FileException(QStringLiteral("Failed to open file: ") + fileHandle.errorString());
}
QTextStream stream(&fileHandle);
QJsonParseError error;
document = QJsonDocument::fromJson(stream.readAll().toUtf8(), &error);
if (document.isNull())
throw FileException(QStringLiteral("Failed to parse file.\n\n") + error.errorString());
if (!document.isObject())
throw FileException(QStringLiteral("Document is malformed."));
const QJsonObject object = document.object();
if (!object.contains(QStringLiteral("world")))
throw FileException(QStringLiteral("Missing world element."));
const QJsonValue rootValue = object.value(QStringLiteral("world"));
if (!rootValue.isObject())
throw FileException(QStringLiteral("World element is malformed."));
const QJsonObject root = rootValue.toObject();
if (!root.contains(QStringLiteral("width")))
throw FileException(QStringLiteral("Width attribute missing."));
if (!root.contains(QStringLiteral("height")))
throw FileException(QStringLiteral("Height attribute missing."));
bool ok = true;
width = root.value(QStringLiteral("width")).toString().toUInt(&ok);
if (!ok) throw FileException(QStringLiteral("Width attribute invalid."));
height = root.value(QStringLiteral("height")).toString().toUInt(&ok);
if (!ok) throw FileException(QStringLiteral("Height attribute invalid."));
if (!root.contains(QStringLiteral("generations")))
generations = 0;
else
{
generations = root.value(QStringLiteral("generations")).toString().toULongLong(&ok);
if (!ok) throw FileException(QStringLiteral("Generations attribute invalid."));
}
const QJsonValue array = root.value(QStringLiteral("cells"));
if (!array.isArray())
throw FileException(QStringLiteral("Cells array missing."));
cells = array.toArray();
iterator = cells.begin();
}
void JsonFile::readCoordinate(quint32& x, quint32& y)
{
const QJsonValue value = *iterator;
++iterator;
if (!value.isObject())
throw FileException(QStringLiteral("Cell value is not an object."));
const QJsonObject cell = value.toObject();
if (!cell.contains(QStringLiteral("x")))
throw FileException(QStringLiteral("Missing x coordinate."));
if (!cell.contains(QStringLiteral("y")))
throw FileException(QStringLiteral("Missing y coordinate."));
bool ok = true;
x = cell.value(QStringLiteral("x")).toString().toUInt(&ok);
if (!ok) throw FileException(QStringLiteral("x coordinate has invalid format."));
y = cell.value(QStringLiteral("y")).toString().toUInt(&ok);
if (!ok) throw FileException(QStringLiteral("y coordinate has invalid format."));
}
bool JsonFile::hasNext() const noexcept
{
return iterator != cells.end();
}
void JsonFile::rewind() noexcept
{
iterator = cells.begin();
}
void JsonFile::write(const QString& filePath, const Headway::World& biotope)
{
QJsonDocument document;
QJsonObject object;
QJsonObject root;
root.insert(QStringLiteral("width"), QString::number(biotope.width()));
root.insert(QStringLiteral("height"), QString::number(biotope.height()));
root.insert(QStringLiteral("generations"), QString::number(biotope.generations()));
QJsonArray cells;
for (quint32 y = 0; y < biotope.height(); ++y)
{
for (quint32 x = 0; x < biotope.width(); ++x)
{
if (biotope.isAlive(x, y)) // save alive cells only
{
QJsonObject item;
item.insert(QStringLiteral("x"), QString::number(x));
item.insert(QStringLiteral("y"), QString::number(y));
cells.append(item);
}
}
}
root.insert(QStringLiteral("cells"), cells);
object.insert(QStringLiteral("world"), root);
document.setObject(object);
QFile fileHandle(filePath);
if (!fileHandle.open(QIODevice::WriteOnly | QIODevice::Text))
{
throw FileException(QStringLiteral("Failed to open file: ") + fileHandle.errorString());
}
const QString text = QString::fromUtf8(document.toJson(QJsonDocument::Indented));
QTextStream stream(&fileHandle);
stream << text;
}