annotate common/json.cpp @ 46:131551c901ae

Plugin logger: reorder keywords
author David Demelier <markand@malikania.fr>
date Mon, 29 Feb 2016 13:12:15 +0100
parents 03068f5ed79d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * json.cpp -- C++14 JSON manipulation using jansson parser
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #include <jansson.h>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
20
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <sstream>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
22
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include "json.h"
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
24
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 namespace irccd {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 namespace json {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
28
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 namespace {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
30
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 void readObject(Value &parent, json_t *object);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 void readArray(Value &parent, json_t *array);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 Value readValue(json_t *v)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
36 if (json_is_null(v))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
37 return Value(nullptr);
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
38 if (json_is_string(v))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
39 return Value(json_string_value(v));
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
40 if (json_is_real(v))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
41 return Value(json_number_value(v));
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
42 if (json_is_integer(v))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
43 return Value(static_cast<int>(json_integer_value(v)));
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
44 if (json_is_boolean(v))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
45 return Value(json_boolean_value(v));
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 if (json_is_object(v)) {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
47 Value object(Type::Object);
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
48
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 readObject(object, v);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
50
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 return object;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 if (json_is_array(v)) {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
54 Value array(Type::Array);
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 readArray(array, v);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
57
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 return array;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
60
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
61 return Value();
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
63
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 void readObject(Value &parent, json_t *object)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
66 const char *key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 json_t *value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
68
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
69 json_object_foreach(object, key, value)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 parent.insert(key, readValue(value));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
72
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 void readArray(Value &parent, json_t *array)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 size_t index;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 json_t *value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
77
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
78 json_array_foreach(array, index, value)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 parent.append(readValue(value));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
81
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 template <typename Func, typename... Args>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 Value convert(Func fn, Args&&... args)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 json_error_t error;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 json_t *json = fn(std::forward<Args>(args)..., &error);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
87
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
88 if (json == nullptr)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
89 throw Error(error.text, error.source, error.line, error.column, error.position);
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
90
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 Value value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
92
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 if (json_is_object(json)) {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
94 value = Value(Type::Object);
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 readObject(value, json);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 } else {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
97 value = Value(Type::Array);
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 readArray(value, json);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
100
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 json_decref(json);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
102
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 return value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
105
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 std::string indent(int param, int level)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 std::string str;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
109
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
110 if (param < 0)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 str = std::string(level, '\t');
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
112 else if (param > 0)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 str = std::string(param * level, ' ');
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
114
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 return str;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
117
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 } // !namespace
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 void Value::copy(const Value &other)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 switch (other.m_type) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 case Type::Array:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 new (&m_array) std::vector<Value>(other.m_array);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 case Type::Boolean:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 m_boolean = other.m_boolean;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 case Type::Int:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 m_integer = other.m_integer;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 case Type::Object:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 new (&m_object) std::map<std::string, Value>(other.m_object);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 case Type::Real:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 m_number = other.m_number;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
138 case Type::String:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
139 new (&m_string) std::string(other.m_string);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
140 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
144
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 m_type = other.m_type;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
147
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 void Value::move(Value &&other)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 switch (other.m_type) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 case Type::Array:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 new (&m_array) std::vector<Value>(std::move(other.m_array));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 case Type::Boolean:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 m_boolean = other.m_boolean;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 case Type::Int:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 m_integer = other.m_integer;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 case Type::Object:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 new (&m_object) std::map<std::string, Value>(std::move(other.m_object));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 case Type::Real:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 m_number = other.m_number;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 case Type::String:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
167 new (&m_string) std::string(std::move(other.m_string));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
172
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 m_type = other.m_type;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
175
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 Value::Value(Type type)
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
177 : m_type(type)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 switch (m_type) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 case Type::Array:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 new (&m_array) std::vector<Value>();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 case Type::Boolean:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 m_boolean = false;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 case Type::Int:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
187 m_integer = 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 case Type::Object:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 new (&m_object) std::map<std::string, Value>();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 case Type::Real:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 m_number = 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 case Type::String:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 new (&m_string) std::string();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
197 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
202
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 Value::~Value()
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 switch (m_type) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 case Type::Array:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 m_array.~vector<Value>();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
209 case Type::Object:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 m_object.~map<std::string, Value>();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 case Type::String:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 m_string.~basic_string();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
218 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
219
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 bool Value::toBool() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
222 if (m_type != Type::Boolean)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 return false;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
224
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 return m_boolean;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
227
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 double Value::toReal() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
230 if (m_type != Type::Real)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 return 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
232
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 return m_number;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
235
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 int Value::toInt() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
238 if (m_type != Type::Int)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 return 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
240
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 return m_integer;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
243
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 std::string Value::toString(bool coerce) const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 std::string result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
247
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
248 if (m_type == Type::String)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 result = m_string;
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
250 else if (coerce)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 result = toJson();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
252
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 return result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
255
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 Value::Value(const Buffer &buffer)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 *this = convert(json_loads, buffer.text.c_str(), 0);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
259 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
260
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 Value::Value(const File &file)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 *this = convert(json_load_file, file.path.c_str(), 0);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
265
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 std::string Value::toJson(int level, int current) const
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 std::ostringstream oss;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
269
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 switch (m_type) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 case Type::Array: {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 oss << '[' << (level != 0 ? "\n" : "");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
273
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 unsigned total = m_array.size();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 unsigned i = 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 for (const auto &v : m_array) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 oss << indent(level, current + 1) << v.toJson(level, current + 1);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 oss << (++i < total ? "," : "");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 oss << (level != 0 ? "\n" : "");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
281
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
282 oss << (level != 0 ? indent(level, current) : "") << ']';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 case Type::Boolean:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 oss << (m_boolean ? "true" : "false");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 case Type::Int:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 oss << m_integer;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
290 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 case Type::Null:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 oss << "null";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 case Type::Object: {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 oss << '{' << (level != 0 ? "\n" : "");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
296
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
297 unsigned total = m_object.size();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 unsigned i = 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 for (const auto &pair : m_object) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 oss << indent(level, current + 1);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
301
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 /* Key and : */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 oss << "\"" << pair.first << "\":" << (level != 0 ? " " : "");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
304
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 /* Value */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 oss << pair.second.toJson(level, current + 1);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
307
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 /* Comma, new line if needed */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 oss << (++i < total ? "," : "") << (level != 0 ? "\n" : "");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
311
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 oss << (level != 0 ? indent(level, current) : "") << '}';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 case Type::Real:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 oss << m_number;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 case Type::String:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 oss << "\"" << escape(m_string) << "\"";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
324
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 return oss.str();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
326 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
327
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
328 std::string escape(const std::string &value)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 std::string result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
331
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 for (auto it = value.begin(); it != value.end(); ++it) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 switch (*it) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
334 case '\\':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 result += "\\\\";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 case '/':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 result += "\\/";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 case '"':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
341 result += "\\\"";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 case '\b':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 result += "\\b";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
346 case '\f':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
347 result += "\\f";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
349 case '\n':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 result += "\\n";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
351 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 case '\r':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 result += "\\r";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
354 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 case '\t':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
356 result += "\\t";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
358 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
359 result += *it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
360 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
361 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
362 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
363
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
364 return result;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
365 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
366
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
367 } // !json
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
368
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
369 } // !irccd