Coverage Report

Created: 2023-10-14 06:19

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