1//
2// Array.cpp
3//
4// Library: JSON
5// Package: JSON
6// Module: Array
7//
8// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/JSON/Array.h"
16#include "Poco/JSON/Object.h"
17#include "Poco/JSON/Stringifier.h"
18
19
20using Poco::Dynamic::Var;
21
22
23namespace Poco {
24namespace JSON {
25
26
27Array::Array(): _modified(false)
28{
29}
30
31
32Array::Array(const Array& other) : _values(other._values),
33 _pArray(other._pArray),
34 _modified(other._modified)
35{
36}
37
38
39Array::Array(Array&& other) :
40 _values(std::move(other._values)),
41 _pArray(!other._modified ? other._pArray : 0),
42 _modified(other._modified)
43{
44 _pArray = 0;
45}
46
47
48Array &Array::operator=(const Array& other)
49{
50 if (&other != this)
51 {
52 _values = other._values;
53 _pArray = other._pArray;
54 _modified = other._modified;
55 }
56 return *this;
57}
58
59
60Array &Array::operator= (Array&& other)
61{
62 if (&other != this)
63 {
64 _values = std::move(other._values);
65 _pArray = other._pArray;
66 other._pArray = 0;
67 _modified = other._modified;
68 }
69 return *this;
70}
71
72
73Array::~Array()
74{
75}
76
77
78Var Array::get(unsigned int index) const
79{
80 Var value;
81 try
82 {
83 value = _values.at(index);
84 }
85 catch (std::out_of_range&)
86 {
87 //Ignore, we return an empty value
88 }
89 return value;
90}
91
92
93Array::Ptr Array::getArray(unsigned int index) const
94{
95 Array::Ptr result;
96
97 Var value = get(index);
98 if (value.type() == typeid(Array::Ptr))
99 {
100 result = value.extract<Array::Ptr>();
101 }
102 return result;
103}
104
105
106Object::Ptr Array::getObject(unsigned int index) const
107{
108 Object::Ptr result;
109
110 Var value = get(index);
111 if (value.type() == typeid(Object::Ptr))
112 {
113 result = value.extract<Object::Ptr>();
114 }
115 return result;
116}
117
118
119bool Array::isNull(unsigned int index) const
120{
121 if (index < _values.size())
122 {
123 Dynamic::Var value = _values[index];
124 return value.isEmpty();
125 }
126 return true;
127}
128
129
130bool Array::isObject(unsigned int index) const
131{
132 Var value = get(index);
133 return isObject(value);
134}
135
136
137bool Array::isObject(const Dynamic::Var& value) const
138{
139 return value.type() == typeid(Object::Ptr);
140}
141
142
143bool Array::isObject(ConstIterator& it) const
144{
145 return it!= end() && isObject(*it);
146}
147
148
149void Array::stringify(std::ostream& out, unsigned int indent, int step) const
150{
151 if (step == -1) step = indent;
152
153 out << "[";
154
155 if (indent > 0) out << std::endl;
156
157 for (ValueVec::const_iterator it = _values.begin(); it != _values.end();)
158 {
159 for (int i = 0; i < indent; i++) out << ' ';
160
161 Stringifier::stringify(*it, out, indent + step, step);
162
163 if (++it != _values.end())
164 {
165 out << ",";
166 if (step > 0) out << '\n';
167 }
168 }
169
170 if (step > 0) out << '\n';
171
172 if (indent >= step) indent -= step;
173
174 for (int i = 0; i < indent; i++)
175 out << ' ';
176
177 out << "]";
178}
179
180
181void Array::resetDynArray() const
182{
183 if (!_pArray)
184 _pArray = new Poco::Dynamic::Array;
185 else
186 _pArray->clear();
187}
188
189
190Array::operator const Poco::Dynamic::Array& () const
191{
192 if (!_values.size())
193 {
194 resetDynArray();
195 }
196 else if (_modified)
197 {
198 ValueVec::const_iterator it = _values.begin();
199 ValueVec::const_iterator end = _values.end();
200 resetDynArray();
201 int index = 0;
202 for (; it != end; ++it, ++index)
203 {
204 if (isObject(it))
205 {
206 _pArray->insert(_pArray->end(), Poco::JSON::Object::makeStruct(getObject(index)));
207 }
208 else if (isArray(it))
209 {
210 _pArray->insert(_pArray->end(), makeArray(getArray(index)));
211 }
212 else
213 {
214 _pArray->insert(_pArray->end(), *it);
215 }
216 }
217 _modified = false;
218 }
219
220 return *_pArray;
221}
222
223
224Poco::Dynamic::Array Array::makeArray(const JSON::Array::Ptr& arr)
225{
226 Poco::Dynamic::Array vec;
227
228 JSON::Array::ConstIterator it = arr->begin();
229 JSON::Array::ConstIterator end = arr->end();
230 int index = 0;
231 for (; it != end; ++it, ++index)
232 {
233 if (arr->isObject(it))
234 {
235 Object::Ptr pObj = arr->getObject(index);
236 DynamicStruct str = Poco::JSON::Object::makeStruct(pObj);
237 vec.insert(vec.end(), str);
238 }
239 else if (arr->isArray(it))
240 {
241 Array::Ptr pArr = arr->getArray(index);
242 std::vector<Poco::Dynamic::Var> v = makeArray(pArr);
243 vec.insert(vec.end(), v);
244 }
245 else
246 vec.insert(vec.end(), *it);
247 }
248
249 return vec;
250}
251
252
253void Array::clear()
254{
255 _values.clear();
256 _pArray = 0;
257}
258
259
260} } // namespace Poco::JSON
261