comparison C++/Json.cpp @ 314:4c3019385769

Json: add iterators TODO: - Test operator->, const_iterator must not let modify - Test const and non const operator[]
author David Demelier <markand@malikania.fr>
date Wed, 25 Feb 2015 13:53:41 +0100
parents ea1a73a7d468
children b67b2da45bb0
comparison
equal deleted inserted replaced
313:cd490a8ab82a 314:4c3019385769
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19 #include <stdexcept>
20
19 #include "Json.h" 21 #include "Json.h"
20 22
21 /* -------------------------------------------------------- 23 /* --------------------------------------------------------
22 * JsonValue implementation 24 * JsonObject
23 * -------------------------------------------------------- */ 25 * -------------------------------------------------------- */
24 26
25 JsonValue::JsonValue(const JsonValue &value) 27 JsonObject JsonValue::toObject() const noexcept
26 : m_handle{json_deep_copy(value.m_handle.get()), json_decref}
27 {
28 }
29
30 JsonValue &JsonValue::operator=(const JsonValue &value)
31 {
32 m_handle = {json_deep_copy(value.m_handle.get()), json_decref};
33 }
34
35 JsonValue::JsonValue(json_t *json)
36 : m_handle{json, json_decref}
37 {
38 }
39
40 JsonValue::JsonValue()
41 : m_handle{json_null(), json_decref}
42 {
43 }
44
45 JsonValue::JsonValue(bool value)
46 : m_handle{json_boolean(value), json_decref}
47 {
48 }
49
50 JsonValue::JsonValue(int value)
51 : m_handle{json_integer(value), json_decref}
52 {
53 }
54
55 JsonValue::JsonValue(double value)
56 : m_handle{json_real(value), json_decref}
57 {
58 }
59
60 JsonValue::JsonValue(std::string value)
61 : m_handle{json_string(value.c_str()), json_decref}
62 {
63 }
64
65 JsonValue::JsonValue(const char *value)
66 : m_handle{json_string(value), json_decref}
67 {
68 }
69
70 JsonType JsonValue::typeOf() const
71 {
72 return static_cast<JsonType>(json_typeof(m_handle.get()));
73 }
74
75 bool JsonValue::isObject() const
76 {
77 return json_is_object(m_handle.get()) != 0;
78 }
79
80 bool JsonValue::isArray() const
81 {
82 return json_is_array(m_handle.get()) != 0;
83 }
84
85 bool JsonValue::isString() const
86 {
87 return json_is_string(m_handle.get()) != 0;
88 }
89
90 bool JsonValue::isReal() const
91 {
92 return json_is_real(m_handle.get()) != 0;
93 }
94
95 bool JsonValue::isTrue() const
96 {
97 return json_is_true(m_handle.get()) != 0;
98 }
99
100 bool JsonValue::isFalse() const
101 {
102 return json_is_false(m_handle.get()) != 0;
103 }
104
105 bool JsonValue::isNull() const
106 {
107 return json_is_null(m_handle.get()) != 0;
108 }
109
110 bool JsonValue::isNumber() const
111 {
112 return json_is_number(m_handle.get()) != 0;
113 }
114
115 bool JsonValue::isInteger() const
116 {
117 return json_is_integer(m_handle.get()) != 0;
118 }
119
120 bool JsonValue::isBoolean() const
121 {
122 return json_is_boolean(m_handle.get()) != 0;
123 }
124
125 std::string JsonValue::toString() const
126 {
127 auto value = json_string_value(m_handle.get());
128
129 return (value == nullptr) ? "" : value;
130 }
131
132 int JsonValue::toInteger() const noexcept
133 {
134 return json_integer_value(m_handle.get());
135 }
136
137 double JsonValue::toReal() const noexcept
138 {
139 return json_real_value(m_handle.get());
140 }
141
142 JsonObject JsonValue::toObject() const
143 { 28 {
144 json_incref(m_handle.get()); 29 json_incref(m_handle.get());
145 30
146 return JsonObject{m_handle.get()}; 31 return JsonObject(m_handle.get());
147 } 32 }
148 33
149 JsonArray JsonValue::toArray() const 34 JsonArray JsonValue::toArray() const noexcept
150 { 35 {
151 json_incref(m_handle.get()); 36 json_incref(m_handle.get());
152 37
153 return JsonArray{m_handle.get()}; 38 return JsonArray(m_handle.get());
154 } 39 }
155 40
156 /* -------------------------------------------------------- 41 /* --------------------------------------------------------
157 * JsonArray 42 * JsonArray
158 * -------------------------------------------------------- */ 43 * -------------------------------------------------------- */
159 44
160 JsonArray::JsonArray() 45 JsonValue JsonArray::at(int index) const
161 : JsonValue{json_array()}
162 { 46 {
163 }
164
165 unsigned JsonArray::size() const noexcept
166 {
167 return json_array_size(m_handle.get());
168 }
169
170 void JsonArray::push(const JsonValue &value)
171 {
172 json_array_insert(m_handle.get(), 0, value.m_handle.get());
173 }
174
175 void JsonArray::append(const JsonValue &value)
176 {
177 json_array_append(m_handle.get(), value.m_handle.get());
178 }
179
180 void JsonArray::insert(const JsonValue &value, int index)
181 {
182 json_array_insert(m_handle.get(), index, value.m_handle.get());
183 }
184
185 JsonValue JsonArray::operator[](int index) const
186 {
187 if (typeOf() != JsonType::Array)
188 throw JsonError{"not an array"};
189
190 auto value = json_array_get(m_handle.get(), index); 47 auto value = json_array_get(m_handle.get(), index);
191 48
192 if (value == nullptr) 49 if (value == nullptr)
193 throw JsonError{"index out of bounds"}; 50 throw JsonError{"index out of bounds"};
194 51
195 json_incref(value); 52 json_incref(value);
196 53
197 return JsonValue{value}; 54 return JsonValue{value};
198 } 55 }
199 56
57 JsonValue JsonArray::operator[](int index) const noexcept
58 {
59 auto value = json_array_get(m_handle.get(), index);
60
61 if (value == nullptr)
62 return JsonValue();
63
64 json_incref(value);
65
66 return JsonValue(value);
67 }
68
69 JsonArray::Ref JsonArray::operator[](int index) noexcept
70 {
71 auto value = json_array_get(m_handle.get(), index);
72
73 if (value == nullptr)
74 value = json_null();
75 else
76 json_incref(value);
77
78 return Ref(value, *this, index);
79 }
80
200 /* -------------------------------------------------------- 81 /* --------------------------------------------------------
201 * JsonObject 82 * JsonObject
202 * -------------------------------------------------------- */ 83 * -------------------------------------------------------- */
203 84
204 JsonObject::JsonObject() 85 JsonObject::Ref JsonObject::operator[](const std::string &name)
205 : JsonValue{json_object()}
206 { 86 {
87 if (typeOf() != JsonType::Object)
88 return Ref(JsonValue(), *this, name);
89
90 auto value = json_object_get(m_handle.get(), name.c_str());
91
92 json_incref(value);
93
94 return Ref(value, *this, name);
207 } 95 }
208 96
209 JsonValue JsonObject::operator[](const std::string &name) const 97 JsonValue JsonObject::operator[](const std::string &name) const
210 { 98 {
211 if (typeOf() != JsonType::Object) 99 if (typeOf() != JsonType::Object)
212 throw JsonError{"not an object"}; 100 return JsonValue();
213 101
214 auto value = json_object_get(m_handle.get(), name.c_str()); 102 auto value = json_object_get(m_handle.get(), name.c_str());
215 103
216 if (value == nullptr) 104 if (value == nullptr)
217 throw JsonError{"key " + name + +" not found"}; 105 return JsonValue();
218 106
219 json_incref(value); 107 json_incref(value);
220 108
221 return JsonValue{value}; 109 return JsonValue(value);
222 }
223
224 void JsonObject::set(const std::string &key, const JsonValue &value)
225 {
226 json_object_set(m_handle.get(), key.c_str(), value.m_handle.get());
227 } 110 }
228 111
229 /* -------------------------------------------------------- 112 /* --------------------------------------------------------
230 * JsonReaderFile 113 * JsonDocument
231 * -------------------------------------------------------- */ 114 * -------------------------------------------------------- */
232 115
233 JsonReaderFile::JsonReaderFile(std::string path) 116 JsonValue JsonDocument::read(std::string content, int flags) const
234 : m_path{std::move(path)}
235 { 117 {
118 json_error_t error;
119 json_t *json = json_loads(content.c_str(), flags, &error);
120
121 if (json == nullptr)
122 throw JsonError(error);
123
124 return JsonValue(json);
236 } 125 }
237 126
238 JsonValue JsonReaderFile::read() 127 JsonValue JsonDocument::read(std::ifstream &stream, int flags) const
239 { 128 {
240 json_error_t error; 129 if (!stream.is_open())
241 json_t *handle = json_load_file(m_path.c_str(), 0, &error); 130 throw JsonError("File not opened");
242 131
243 if (handle == nullptr) 132 stream.seekg(0, stream.end);
244 throw JsonError{error}; 133 auto length = stream.tellg();
134 stream.seekg(0, stream.beg);
245 135
246 return JsonValue{handle}; 136 std::string buffer;
137 buffer.resize(length, ' ');
138
139 stream.read(&buffer[0], length);
140 stream.close();
141
142 return read(std::move(buffer), flags);
247 } 143 }
248 144
249 /* -------------------------------------------------------- 145 JsonDocument::JsonDocument(std::ifstream &stream, int flags)
250 * JsonWriterFile
251 * -------------------------------------------------------- */
252
253 JsonWriterFile::JsonWriterFile(std::string path)
254 : m_path{std::move(path)}
255 { 146 {
147 m_value = read(stream, flags);
256 } 148 }
257 149
258 void JsonWriterFile::write(const JsonValue &value) 150 JsonDocument::JsonDocument(std::ifstream &&stream, int flags)
259 { 151 {
260 if (json_dump_file(value, m_path.c_str(), 0) < 0) 152 m_value = read(stream, flags);
261 throw JsonError{"Failed to write file: " + m_path};
262 } 153 }
154
155 JsonDocument::JsonDocument(std::string content, int flags)
156 {
157 m_value = read(std::move(content), flags);
158 }