loom

Форк
0
/
Serialization.cpp 
235 строк · 7.0 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo
7
*/
8

9
#include "simodo/variable/json/Serialization.h"
10
#include "simodo/variable/json/parser/JsonRdp.h"
11
#include "simodo/inout/convert/functions.h"
12
#include "simodo/inout/token/FileStream.h"
13
#include "simodo/inout/token/RefBufferStream.h"
14
#include "simodo/variable/json/Rpc.h"
15

16
#include <fstream>
17
#include <sstream>
18

19
namespace simodo::variable
20
{
21
    namespace
22
    {
23
        class StringReporter: public inout::Reporter_abstract
24
        {
25
            mutable std::string _message;
26

27
        public:
28
            virtual void report(const inout::SeverityLevel level,
29
                                const inout::Location & ,
30
                                const std::string & briefly,
31
                                const std::string & atlarge) const override
32
            {
33
                _message += inout::getSeverityLevelName(level) + briefly;
34
                if (!atlarge.empty())
35
                    _message += " (" + atlarge + ")\n";
36
            }
37

38
            std::string message() const { return _message; }
39
        };
40

41
        void printJson(const Value & value, std::ostream & out, int level, bool compress, bool skip_empty_parameters)
42
        {
43
            switch (value.type())
44
            {
45
            case ValueType::Bool:
46
                out << (value.getBool() ? "true" : "false");
47
                break;
48
            case ValueType::Int:
49
                out << value.getInt();
50
                break;
51
            case ValueType::Float:
52
                out << value.getFloat(); // clearNumberFractionalPart
53
                break;
54
            case ValueType::String:
55
                {
56
                    std::u16string str = value.getString();
57
                    inout::replaceAll(str,u"\\",u"\\\\");
58
                    inout::replaceAll(str,u"\"",u"\\\"");
59
                    out << "\"" << inout::toU8(str) << "\"";
60
                }
61
                break;
62
            case ValueType::Null:
63
            // case ValueType::Undefined:
64
                out << "null";
65
                break;
66
            case ValueType::Object:
67
                {
68
                    const std::shared_ptr<Object> object = value.getObject();
69

70
                    out << "{";
71

72
                    if (!compress)
73
                        out << std::endl;
74

75
                    int i = 0;
76

77
                    for(const Variable & var : object->variables()) {
78
                        // if (var.type() == ValueType::Null)
79
                        //     continue;
80
                        if (level <= 1 && skip_empty_parameters && var.type() == ValueType::Null)
81
                            continue;
82

83
                        if (i++ > 0) {
84
                            out << ",";
85
                            if (!compress)
86
                                out << std::endl;
87
                        }
88

89
                        if (!compress)
90
                            for(int i=0; i < level; ++i)
91
                                out << "\t";
92

93
                        if (!compress)
94
                            out << "\"" << inout::toU8(var.name()) << "\" : ";
95
                        else
96
                            out << "\"" << inout::toU8(var.name()) << "\":";
97

98
                        printJson(var.value(), out, level+1, compress, skip_empty_parameters);
99
                    }
100

101
                    if (!compress)
102
                        out << std::endl;
103

104
                    if (!compress) // -V581
105
                        for(int i=0; i < level-1; ++i)
106
                            out << "\t";
107

108
                    out << "}";
109
                }
110
                break;
111
            case ValueType::Array:
112
                {
113
                    std::shared_ptr<Array> array = value.getArray();
114

115
                    out << "[";
116

117
                    if (!compress)
118
                        out << std::endl;
119

120
                    int i = 0;
121

122
                    for(const Value & v : array->values())
123
                    {
124
                        if (i++ > 0) {
125
                            out << ",";
126
                            if (!compress)
127
                                out << std::endl;
128
                        }
129

130
                        if (!compress)
131
                            for(int i=0; i < level; ++i)
132
                                out << "\t";
133

134
                        printJson(v, out, level+1, compress, skip_empty_parameters);
135
                    }
136

137
                    if (!compress)
138
                        out << std::endl;
139

140
                    if (!compress) // -V581
141
                        for(int i=0; i < level-1; ++i)
142
                            out << "\t";
143

144
                    out << "]";
145
                }
146
                break;
147
            default:
148
                out << "\"unrecognizable type of value: " + getValueTypeName(value.type())+ "\"";
149
                break;
150
            }
151
        }
152
    }
153

154
    std::string loadJson(const std::string &file_name, Value &value)
155
    {
156
        StringReporter  reporter;
157
        JsonRdp         parser(reporter, file_name, value);
158
        std::string     result;
159

160
        bool ok = parser.parse();
161

162
        if (!ok)
163
            result = reporter.message();
164

165
        return result;
166
    }
167

168
    std::string loadJson(std::istream &in, Value &value, const std::string &file_name)
169
    {
170
        inout::InputStream  stream(in);
171
        StringReporter      reporter;
172
        JsonRdp             parser(reporter, file_name, value);
173
        std::string         result;
174

175
        bool ok = parser.parse(stream);
176

177
        if (!ok)
178
            result = reporter.message();
179

180
        return result;
181
    }
182

183
    bool saveJson(const Value &value, std::ostream &out, bool compress, bool skip_empty_parameters)
184
    {
185
        if (out.fail())
186
            return false;
187

188
        printJson(value, out, 1, compress, skip_empty_parameters);
189

190
        out.flush();
191

192
        return out.good();
193
    }
194

195
    bool saveJson(const Value &value, const std::string &file_name, bool compress, bool skip_empty_parameters)
196
    {
197
        std::ofstream   out(file_name);
198

199
        if (!out)
200
            return false;
201

202
        return saveJson(value, out, compress, skip_empty_parameters);
203
    }
204

205
    bool saveJson(const JsonRpc & rpc, std::ostream & out, bool compress, bool skip_empty_parameters)
206
    {
207
        return saveJson(rpc.value(), out, compress, skip_empty_parameters);
208
    }
209

210
    Value fromJson(const std::string & json_string)
211
    {
212
        std::istringstream  is(json_string);
213
        inout::InputStream  input(is);
214
        Value               res;
215
        StringReporter      reporter;
216
        JsonRdp             parser(reporter,{},res);
217

218
        parser.parse(input);
219

220
        return res;
221
    }
222

223
    Value fromJson(const std::u16string & json_string)
224
    {
225
        return fromJson(inout::toU8(json_string));
226
    }
227

228
    std::string toJson(const Value & value, bool compress, bool skip_empty_parameters)
229
    {
230
        std::ostringstream os;
231
        saveJson(value, os, compress, skip_empty_parameters);
232
        return os.str();
233
    }
234

235
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.