Mercurial > code
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 } |