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