-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjson_builder.cpp
205 lines (179 loc) · 5.37 KB
/
json_builder.cpp
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "json_builder.h"
#include <iostream>
namespace json {
// --- Builder -----------------------------------------------------------
Builder& Builder::Value(Node value)
{
AddNode(value);
return *this;
}
KeyContext Builder::Key(std::string key)
{
KeyContext context(*this);
if (nodes_stack_.size() && nodes_stack_.back()->IsDict())
{
Dict& cur = const_cast<Dict&>(nodes_stack_.back()->AsDict());
cur.emplace(key, key);
nodes_stack_.push_back(&cur.at(key));
}
else
{
std::cout << "something wrong with key" << std::endl;
throw std::logic_error("something wrong with key");
}
return context;
}
ArrayContext Builder::StartArray()
{
ArrayContext context(*this);
nodes_stack_.push_back(AddNode(Array{}));
return context;
}
Builder& Builder::EndArray()
{
if (nodes_stack_.size() && nodes_stack_.back()->IsArray())
{
nodes_stack_.pop_back();
}
else
{
std::cout << "something wrong with array" << std::endl;
throw std::logic_error("something wrong with array");
}
return *this;
}//*/
DictContext Builder::StartDict()
{
DictContext context(*this);
nodes_stack_.push_back(AddNode(Dict{}));
return context;
}
Builder& Builder::EndDict()
{
if (nodes_stack_.size() && nodes_stack_.back()->IsDict())
{
nodes_stack_.pop_back();
}
else
{
std::cout << "something wrong with dictionary" << std::endl;
throw std::logic_error("something wrong with dictionary");
}
return *this;
}//*/
// --- Additional method --------------------------------------------------
Node* Builder::AddNode(Node node)
{
// working with first node
if (nodes_stack_.size() == 0 && root_.IsNull())
{
root_ = Node(node);
return &root_;
}
// working with array
else if (nodes_stack_.size() && nodes_stack_.back()->IsArray())
{
Array& cur = const_cast<Array&>(nodes_stack_.back()->AsArray());
cur.push_back(node);
return &cur.back();
}
// working with dictionary
else if (nodes_stack_.size() && nodes_stack_.back()->IsString())
{
const std::string key = nodes_stack_.back()->AsString();
nodes_stack_.pop_back();
if (nodes_stack_.back()->IsDict())
{
Dict& cur = const_cast<Dict&>(nodes_stack_.back()->AsDict());
cur[key] = node;
return &cur.at(key);
}
else
{
std::cout << "something wrong with key and value" << std::endl;
throw std::logic_error("something wrong with key and value");
}
}
else
{
std::cout << "something wrong with add node" << std::endl;
throw std::logic_error("something wrong with add node");
}
}
// --- Builder::Build() method --------------------------------------------
Node Builder::Build()
{
if (root_.IsNull() || nodes_stack_.size())
{
std::cout << "something wrong with building" << std::endl;
throw std::logic_error("something wrong with building");
}
return root_;
}
// --- Context classes ----------------------------------------------------
// ----- ValueValueContext methods ----------------------------------------
ValueValueContext ValueValueContext::Value(Node value)
{
return builder_.Value(value);
}
ArrayContext ValueValueContext::StartArray()
{
return builder_.StartArray();
}
Builder& ValueValueContext::EndArray()
{
return builder_.EndArray();
}
DictContext ValueValueContext::StartDict()
{
return builder_.StartDict();
}
// ----- ValueKeyConext methods -------------------------------------------
KeyContext ValueKeyContext::Key(std::string s)
{
return builder_.Key(s);
}
Builder& ValueKeyContext::EndDict()
{
return builder_.EndDict();
}
// ----- KeyConext methods ------------------------------------------------
ValueKeyContext KeyContext::Value(Node value)
{
return builder_.Value(value);
}
ArrayContext KeyContext::StartArray()
{
return builder_.StartArray();
}
DictContext KeyContext::StartDict()
{
return builder_.StartDict();
}
// ----- ArrayContext methods ---------------------------------------------
ValueValueContext ArrayContext::Value(Node value)
{
return builder_.Value(value);
}
ArrayContext ArrayContext::StartArray()
{
return builder_.StartArray();
}
Builder& ArrayContext::EndArray()
{
return builder_.EndArray();
}
DictContext ArrayContext::StartDict()
{
return builder_.StartDict();
}
// ----- DictContext methods ----------------------------------------------
KeyContext DictContext::Key(std::string s)
{
return builder_.Key(s);
}
Builder& DictContext::EndDict()
{
return builder_.EndDict();
}
} // namespace json