structurewriter.cpp 3.11 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
\file structurewriter.cpp
\date 13/05/2021
\author Yann Boucher
\version 1
\brief StructureWriter
**/


#include "structurewriter.hpp"

#include "structure.hpp"

#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>

18
std::string JSONStructureWriter::save_structure(const Structure& s) const
19
20
21
22
{
    QJsonObject root;
    QJsonArray cells;

23
    for (const auto& pair : s)
24
25
26
27
28
29
30
31
32
    {
        QJsonObject entry;
        entry.insert("x", pair.first.x);
        entry.insert("y", pair.first.y);
        entry.insert("state", (int)pair.second);

        cells.append(entry);
    }

33
34
35
36
    root.insert("author", QString::fromStdString(s.author));
    root.insert("title", QString::fromStdString(s.title));
    root.insert("desc", QString::fromStdString(s.desc));
    root.insert("date", QString::fromStdString(s.date));
37
38
39
40
41
42
    root.insert("cells", cells);

    QJsonDocument doc(root);
    return doc.toJson().toStdString();
}

43
std::string RLEStructureWriter::save_structure(const Structure& s) const
44
45
{
    std::string result;
46
47
48
49
50
51
52
    if (!s.title.empty())
        result += "#N " + s.title + "\n";
    if (!s.author.empty() || !s.date.empty())
        result += "#O " + s.author + " " + s.date + "\n";
    if (!s.desc.empty())
        result += "#C " + s.desc;

53
54
    result += "x = " + std::to_string(s.width()) + ", ";
    result += "y = " + std::to_string(s.height()) + "\n";
55

56
57
58
59
60
61
62
63
64
    m_x = m_y = 0;
    auto it = s.begin();
    auto end = s.end();
    while (it != end)
        result += output_line(it, end);

    result += "!";

    return result;
65
66
}

67
std::string RLEStructureWriter::state_to_str(unsigned state) const
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{
    if (state == 0)
        return "b";
    if (state == 1)
        return "o";
    if (state >= 1 && state <= 24)
        return std::string(1, state-1 + 'A');
    else
    {
        char page_char = ((state-25)/24) + 'p';
        char offset_char = (state-25)%24 + 'A';

        return std::string(1, page_char) + std::string(1, offset_char);
    }
}
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

std::string RLEStructureWriter::output_line(Structure::iterator& it, Structure::iterator end) const
{
    std::string output;
    unsigned line_difference = it->first.y - m_y;

    m_x = 0;
    m_y = it->first.y;
    output += rle("$", line_difference);

    while (it != end && it->first.y == (int)m_y)
        output += output_rle_state(it, end);

    return output;
}

std::string RLEStructureWriter::output_rle_state(Structure::iterator& it, Structure::iterator end) const
{
    unsigned zero_pad = it->first.x - m_x;
    unsigned state = it->second;
    unsigned len = 1;

    while (std::next(it) != end &&
           std::next(it)->second == state &&
           std::next(it)->first.x == it->first.x + 1 &&
           std::next(it)->first.y == it->first.y)
    {
        std::advance(it, 1);
        ++len;
    }

    m_x = it->first.x + 1;
    std::advance(it, 1);
    // pad until first non-null state
    return rle(state_to_str(0), zero_pad) + rle(state_to_str(state), len);
}

std::string RLEStructureWriter::rle(const std::string &val, unsigned count) const
{
    if (count == 0)
        return "";
    else if (count == 1)
        return val;
    else
        return std::to_string(count) + val;
}