Coverage Report

Created: 2025-06-22 07:07

/src/oatpp/src/oatpp/data/mapping/Tree.cpp
Line
Count
Source (jump to first uncovered line)
1
/***************************************************************************
2
 *
3
 * Project         _____    __   ____   _      _
4
 *                (  _  )  /__\ (_  _)_| |_  _| |_
5
 *                 )(_)(  /(__)\  )( (_   _)(_   _)
6
 *                (_____)(__)(__)(__)  |_|    |_|
7
 *
8
 *
9
 * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 *     http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 *
23
 ***************************************************************************/
24
25
#include "Tree.hpp"
26
27
#include "oatpp/data/stream/BufferStream.hpp"
28
29
namespace oatpp { namespace data { namespace mapping {
30
31
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32
// Tree::Attributes
33
34
Tree::Attributes::Attributes()
35
9.04M
  : m_attributes(nullptr)
36
9.04M
{}
37
38
Tree::Attributes::Attributes(const Attributes& other)
39
0
  : Attributes()
40
0
{
41
0
  operator=(other);
42
0
}
43
44
Tree::Attributes::Attributes(Attributes&& other) noexcept
45
7.94M
  : m_attributes(other.m_attributes)
46
7.94M
{
47
7.94M
  other.m_attributes = nullptr;
48
7.94M
}
49
50
4.65M
Tree::Attributes& Tree::Attributes::operator = (const Attributes& other) {
51
52
4.65M
  if(other.m_attributes) {
53
54
0
    if(m_attributes) {
55
0
      *m_attributes = *other.m_attributes;
56
0
    } else {
57
0
      m_attributes = new Attrs(*other.m_attributes);
58
0
    }
59
60
0
    for(auto & po : m_attributes->order){
61
0
      po.second = &m_attributes->map.at(po.first.lock());
62
0
    }
63
64
4.65M
  } else {
65
4.65M
    delete m_attributes;
66
4.65M
    m_attributes = nullptr;
67
4.65M
  }
68
69
4.65M
  return *this;
70
4.65M
}
71
72
81.6k
Tree::Attributes& Tree::Attributes::operator = (Attributes&& other) noexcept {
73
74
81.6k
  delete m_attributes;
75
76
81.6k
  m_attributes = other.m_attributes;
77
81.6k
  other.m_attributes = nullptr;
78
79
81.6k
  return *this;
80
81.6k
}
81
82
16.9M
Tree::Attributes::~Attributes() {
83
16.9M
  delete m_attributes;
84
16.9M
  m_attributes = nullptr;
85
16.9M
}
86
87
0
void Tree::Attributes::initAttributes() {
88
0
  if(m_attributes == nullptr)  {
89
0
    m_attributes = new Attrs();
90
0
  }
91
0
}
92
93
0
type::String& Tree::Attributes::operator [] (const type::String& key) {
94
0
  initAttributes();
95
0
  auto it = m_attributes->map.find(key);
96
0
  if(it == m_attributes->map.end()) {
97
0
    auto& result = m_attributes->map[key];
98
0
    m_attributes->order.emplace_back(key.getPtr(), &result);
99
0
    return result;
100
0
  }
101
0
  return it->second;
102
0
}
103
104
0
const type::String& Tree::Attributes::operator [] (const type::String& key) const {
105
0
  if(m_attributes != nullptr) {
106
0
    auto it = m_attributes->map.find(key);
107
0
    if (it != m_attributes->map.end()) {
108
0
      return it->second;
109
0
    }
110
0
  }
111
0
  throw std::runtime_error("[oatpp::data::mapping::Tree::Attributes::operator []]: const operator[] can't add items.");
112
0
}
113
114
0
std::pair<type::String, std::reference_wrapper<type::String>> Tree::Attributes::operator [] (v_uint64 index) {
115
0
  if(m_attributes != nullptr) {
116
0
    auto &item = m_attributes->order.at(index);
117
0
    return {item.first.lock(), *item.second};
118
0
  }
119
0
  throw std::runtime_error("[oatpp::data::mapping::Tree::Attributes::operator []]: const operator[] can't get item - empty attributes.");
120
0
}
121
122
0
std::pair<type::String, std::reference_wrapper<const type::String>> Tree::Attributes::operator [] (v_uint64 index) const {
123
0
  if(m_attributes != nullptr) {
124
0
    auto &item = m_attributes->order.at(index);
125
0
    return {item.first.lock(), *item.second};
126
0
  }
127
0
  throw std::runtime_error("[oatpp::data::mapping::Tree::Attributes::operator []]: const operator[] can't get item - empty attributes.");
128
0
}
129
130
0
type::String Tree::Attributes::get(const type::String& key) const {
131
0
  if(m_attributes == nullptr) return nullptr;
132
0
  auto it = m_attributes->map.find(key);
133
0
  if(it != m_attributes->map.end()) {
134
0
    return it->second;
135
0
  }
136
0
  return nullptr;
137
0
}
138
139
0
bool Tree::Attributes::empty() const {
140
0
  return m_attributes == nullptr || m_attributes->map.empty();
141
0
}
142
143
0
v_uint64 Tree::Attributes::size() const {
144
0
  if(m_attributes) {
145
0
    return m_attributes->map.size();
146
0
  }
147
0
  return 0;
148
0
}
149
150
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
151
// Tree
152
153
Tree::Tree()
154
9.04M
  : m_type(Type::UNDEFINED)
155
9.04M
  , m_data(0)
156
9.04M
{}
157
158
Tree::Tree(const Tree& other)
159
4.65M
  : Tree()
160
4.65M
{
161
4.65M
  setCopy(other);
162
4.65M
}
163
164
Tree::Tree(Tree&& other) noexcept
165
7.94M
  : m_type(other.m_type)
166
7.94M
  , m_data(other.m_data)
167
7.94M
  , m_attributes(std::move(other.m_attributes))
168
7.94M
{
169
7.94M
  other.m_type = Type::UNDEFINED;
170
7.94M
  other.m_data = 0;
171
7.94M
}
172
173
Tree::Tree(const type::String& value)
174
0
  : Tree()
175
0
{
176
0
  setString(value);
177
0
}
178
179
16.9M
Tree::~Tree() {
180
16.9M
  deleteValueObject();
181
16.9M
}
182
183
0
Tree& Tree::operator = (const Tree& other) {
184
0
  setCopy(other);
185
0
  return *this;
186
0
}
187
188
81.6k
Tree& Tree::operator = (Tree&& other) noexcept {
189
81.6k
  setMove(std::move(other));
190
81.6k
  return *this;
191
81.6k
}
192
193
0
Tree& Tree::operator = (const type::String& value) {
194
0
  setString(value);
195
0
  return *this;
196
0
}
197
198
26.0M
void Tree::deleteValueObject() {
199
200
26.0M
  switch (m_type) {
201
202
16.9M
    case Type::UNDEFINED:
203
204
17.1M
    case Type::NULL_VALUE:
205
206
18.4M
    case Type::INTEGER:
207
18.4M
    case Type::FLOAT:
208
209
18.4M
    case Type::BOOL:
210
211
18.5M
    case Type::INT_8:
212
18.5M
    case Type::UINT_8:
213
18.5M
    case Type::INT_16:
214
18.5M
    case Type::UINT_16:
215
18.5M
    case Type::INT_32:
216
18.5M
    case Type::UINT_32:
217
20.1M
    case Type::INT_64:
218
20.1M
    case Type::UINT_64:
219
220
20.1M
    case Type::FLOAT_32:
221
20.1M
    case Type::FLOAT_64:
222
20.1M
      break;
223
224
3.85M
    case Type::STRING: {
225
3.85M
      auto data = reinterpret_cast<type::String *>(m_data);
226
3.85M
      delete data;
227
3.85M
      break;
228
20.1M
    }
229
1.42M
    case Type::VECTOR: {
230
1.42M
      auto data = reinterpret_cast<std::vector<Tree> *>(m_data);
231
1.42M
      delete data;
232
1.42M
      break;
233
20.1M
    }
234
21.5k
    case Type::MAP: {
235
21.5k
      auto data = reinterpret_cast<TreeMap *>(m_data);
236
21.5k
      delete data;
237
21.5k
      break;
238
20.1M
    }
239
559k
    case Type::PAIRS: {
240
559k
      auto data = reinterpret_cast<std::vector<std::pair<type::String, Tree>> *>(m_data);
241
559k
      delete data;
242
559k
      break;
243
20.1M
    }
244
245
0
    default:
246
      // DO-NOTHING
247
0
      break;
248
249
26.0M
  }
250
26.0M
}
251
252
0
Tree::operator type::String () {
253
0
  return getString();
254
0
}
255
256
0
Tree& Tree::operator [] (const type::String& key) {
257
0
  return getMap()[key];
258
0
}
259
260
0
const Tree& Tree::operator [] (const type::String& key) const {
261
0
  return getMap()[key];
262
0
}
263
264
0
Tree& Tree::operator [] (v_uint64 index) {
265
0
  return getVector().at(index);
266
0
}
267
268
0
const Tree& Tree::operator [] (v_uint64 index) const {
269
0
  return getVector().at(index);
270
0
}
271
272
3.12M
Tree::Type Tree::getType() const {
273
3.12M
  return m_type;
274
3.12M
}
275
276
4.65M
void Tree::setCopy(const Tree& other) {
277
278
4.65M
  deleteValueObject();
279
4.65M
  m_type = other.m_type;
280
4.65M
  m_attributes = other.m_attributes;
281
282
4.65M
  switch (other.m_type) {
283
284
0
    case Type::UNDEFINED:
285
4.26k
    case Type::NULL_VALUE:
286
4.26k
      break;
287
288
0
    case Type::INTEGER:
289
0
    case Type::FLOAT:
290
291
229
    case Type::BOOL:
292
229
    case Type::INT_8:
293
229
    case Type::UINT_8:
294
229
    case Type::INT_16:
295
229
    case Type::UINT_16:
296
229
    case Type::INT_32:
297
3.36k
    case Type::UINT_32:
298
1.09M
    case Type::INT_64:
299
1.09M
    case Type::UINT_64:
300
1.09M
    case Type::FLOAT_32:
301
1.09M
    case Type::FLOAT_64:
302
1.09M
    {
303
1.09M
      m_data = other.m_data;
304
1.09M
      break;
305
1.09M
    }
306
307
1.75M
    case Type::STRING: {
308
1.75M
      auto otherData = reinterpret_cast<type::String *>(other.m_data);
309
1.75M
      if(otherData == nullptr) {
310
0
        throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'STRING'");
311
0
      }
312
1.75M
      auto ptr = new type::String(*otherData);
313
1.75M
      m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
314
1.75M
      break;
315
1.75M
    }
316
1.24M
    case Type::VECTOR: {
317
1.24M
      auto otherData = reinterpret_cast<std::vector<Tree> *>(other.m_data);
318
1.24M
      if(otherData == nullptr) {
319
0
        throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'VECTOR'");
320
0
      }
321
1.24M
      auto ptr = new std::vector<Tree>(*otherData);
322
1.24M
      m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
323
1.24M
      break;
324
1.24M
    }
325
0
    case Type::MAP: {
326
0
      auto otherData = reinterpret_cast<TreeMap *>(other.m_data);
327
0
      if(otherData == nullptr) {
328
0
        throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'MAP'");
329
0
      }
330
0
      auto ptr = new TreeMap(*otherData);
331
0
      m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
332
0
      break;
333
0
    }
334
553k
    case Type::PAIRS: {
335
553k
      auto otherData = reinterpret_cast<std::vector<std::pair<type::String, Tree>> *>(other.m_data);
336
553k
      if(otherData == nullptr) {
337
0
        throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'PAIRS'");
338
0
      }
339
553k
      auto ptr = new std::vector<std::pair<type::String, Tree>>(*otherData);
340
553k
      m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
341
553k
      break;
342
553k
    }
343
344
0
    default:
345
0
      m_data = other.m_data;
346
0
      break;
347
348
4.65M
  }
349
350
4.65M
}
351
352
81.6k
void Tree::setMove(Tree&& other) {
353
354
81.6k
  deleteValueObject();
355
356
81.6k
  m_type = other.m_type;
357
81.6k
  m_data = other.m_data;
358
81.6k
  m_attributes = std::move(other.m_attributes);
359
360
81.6k
  other.m_type = Type::NULL_VALUE;
361
81.6k
  other.m_data = 0;
362
363
81.6k
}
364
365
74.5k
void Tree::setNull() {
366
74.5k
  deleteValueObject();
367
74.5k
  m_type = Type::NULL_VALUE;
368
74.5k
  m_data = 0;
369
74.5k
}
370
371
0
void Tree::setUndefined() {
372
0
  deleteValueObject();
373
0
  m_type = Type::UNDEFINED;
374
0
  m_data = 0;
375
0
}
376
377
1.25M
void Tree::setInteger(v_int64 value) {
378
1.25M
  deleteValueObject();
379
1.25M
  m_type = Type::INTEGER;
380
1.25M
  std::memcpy (&m_data, &value, sizeof(v_int64));
381
1.25M
}
382
383
11.2k
void Tree::setFloat(v_float64 value) {
384
11.2k
  deleteValueObject();
385
11.2k
  m_type = Type::FLOAT;
386
11.2k
  std::memcpy (&m_data, &value, sizeof(v_float64));
387
11.2k
}
388
389
0
void Tree::setString(const type::String& value) {
390
0
  deleteValueObject();
391
0
  m_type = Type::STRING;
392
0
  auto data = new type::String(value);
393
0
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
394
0
}
395
396
2.10M
void Tree::setString(type::String&& value) {
397
2.10M
  deleteValueObject();
398
2.10M
  m_type = Type::STRING;
399
2.10M
  auto data = new type::String(std::move(value));
400
2.10M
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
401
2.10M
}
402
403
0
void Tree::setVector(const std::vector<Tree>& value) {
404
0
  deleteValueObject();
405
0
  m_type = Type::VECTOR;
406
0
  auto data = new std::vector<Tree>(value);
407
0
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
408
0
}
409
410
0
void Tree::setVector(std::vector<Tree>&& value) {
411
0
  deleteValueObject();
412
0
  m_type = Type::VECTOR;
413
0
  auto data = new std::vector<Tree>(std::move(value));
414
0
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
415
0
}
416
417
181k
void Tree::setVector(v_uint64 size) {
418
181k
  deleteValueObject();
419
181k
  m_type = Type::VECTOR;
420
181k
  auto data = new std::vector<Tree>(size);
421
181k
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
422
181k
}
423
424
0
void Tree::setMap(const TreeMap& value) {
425
0
  deleteValueObject();
426
0
  m_type = Type::MAP;
427
0
  auto data = new TreeMap(value);
428
0
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
429
0
}
430
431
21.5k
void Tree::setMap(TreeMap&& value) {
432
21.5k
  deleteValueObject();
433
21.5k
  m_type = Type::MAP;
434
21.5k
  auto data = new TreeMap(std::move(value));
435
21.5k
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
436
21.5k
}
437
438
0
void Tree::setPairs(const std::vector<std::pair<type::String, Tree>>& value) {
439
0
  deleteValueObject();
440
0
  m_type = Type::PAIRS;
441
0
  auto data = new std::vector<std::pair<type::String, Tree>>(value);
442
0
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
443
0
}
444
445
5.76k
void Tree::setPairs(const std::vector<std::pair<type::String, Tree>>&& value) {
446
5.76k
  deleteValueObject();
447
5.76k
  m_type = Type::PAIRS;
448
5.76k
  auto data = new std::vector<std::pair<type::String, Tree>>(std::move(value));
449
5.76k
  m_data = reinterpret_cast<LARGEST_TYPE>(data);
450
5.76k
}
451
452
3.08M
bool Tree::isNull() const {
453
3.08M
  return m_type == Type::NULL_VALUE;
454
3.08M
}
455
456
0
bool Tree::isUndefined() const {
457
0
  return m_type == Type::UNDEFINED;
458
0
}
459
460
753k
bool Tree::isPrimitive() const {
461
753k
  switch (m_type) {
462
463
0
    case Type::UNDEFINED:
464
3.51k
    case Type::NULL_VALUE:
465
3.51k
      return false;
466
467
734k
    case Type::INTEGER:
468
742k
    case Type::FLOAT:
469
470
744k
    case Type::BOOL:
471
744k
    case Type::INT_8:
472
744k
    case Type::UINT_8:
473
744k
    case Type::INT_16:
474
744k
    case Type::UINT_16:
475
744k
    case Type::INT_32:
476
744k
    case Type::UINT_32:
477
744k
    case Type::INT_64:
478
744k
    case Type::UINT_64:
479
744k
    case Type::FLOAT_32:
480
744k
    case Type::FLOAT_64:
481
744k
      return true;
482
483
5.58k
    case Type::STRING:
484
5.59k
    case Type::VECTOR:
485
5.60k
    case Type::MAP:
486
5.60k
    case Type::PAIRS:
487
5.60k
    default:
488
5.60k
      return false;
489
753k
  }
490
491
753k
}
492
493
0
v_int32 Tree::primitiveDataSize() const {
494
0
  switch (m_type) {
495
496
0
    case Type::UNDEFINED:
497
0
    case Type::NULL_VALUE:
498
0
      return -1;
499
500
0
    case Type::INTEGER:
501
0
    case Type::FLOAT: return 8;
502
503
0
    case Type::BOOL:
504
0
    case Type::INT_8:
505
0
    case Type::UINT_8: return 1;
506
507
0
    case Type::INT_16:
508
0
    case Type::UINT_16: return 2;
509
510
0
    case Type::INT_32:
511
0
    case Type::UINT_32: return 4;
512
513
0
    case Type::INT_64:
514
0
    case Type::UINT_64: return 8;
515
516
0
    case Type::FLOAT_32: return 4;
517
0
    case Type::FLOAT_64: return 8;
518
519
0
    case Type::STRING:
520
0
    case Type::VECTOR:
521
0
    case Type::MAP:
522
0
    case Type::PAIRS:
523
0
    default:
524
0
      return -1;
525
0
  }
526
0
}
527
528
0
bool Tree::isFloatPrimitive() const {
529
0
  switch (m_type) {
530
531
0
    case Type::UNDEFINED:
532
0
    case Type::NULL_VALUE:
533
0
    case Type::INTEGER: return false;
534
535
0
    case Type::FLOAT: return true;
536
537
0
    case Type::BOOL:
538
0
    case Type::INT_8:
539
0
    case Type::UINT_8:
540
0
    case Type::INT_16:
541
0
    case Type::UINT_16:
542
0
    case Type::INT_32:
543
0
    case Type::UINT_32:
544
0
    case Type::INT_64:
545
0
    case Type::UINT_64: return false;
546
547
0
    case Type::FLOAT_32:
548
0
    case Type::FLOAT_64: return true;
549
550
0
    case Type::STRING:
551
0
    case Type::VECTOR:
552
0
    case Type::MAP:
553
0
    case Type::PAIRS:
554
0
    default:
555
0
      return false;
556
0
  }
557
0
}
558
559
0
bool Tree::isIntPrimitive() const {
560
0
  switch (m_type) {
561
562
0
    case Type::UNDEFINED:
563
0
    case Type::NULL_VALUE:
564
0
      return false;
565
566
0
    case Type::INTEGER: return true;
567
0
    case Type::FLOAT: return false;
568
569
0
    case Type::BOOL:
570
0
    case Type::INT_8:
571
0
    case Type::UINT_8:
572
0
    case Type::INT_16:
573
0
    case Type::UINT_16:
574
0
    case Type::INT_32:
575
0
    case Type::UINT_32:
576
0
    case Type::INT_64:
577
0
    case Type::UINT_64: return true;
578
579
0
    case Type::FLOAT_32:
580
0
    case Type::FLOAT_64:
581
582
0
    case Type::STRING:
583
0
    case Type::VECTOR:
584
0
    case Type::MAP:
585
0
    case Type::PAIRS:
586
0
    default:
587
0
      return false;
588
0
  }
589
0
}
590
591
870k
bool Tree::isString() const {
592
870k
  return m_type == Type::STRING;
593
870k
}
594
595
0
bool Tree::isVector() const {
596
0
  return m_type == Type::VECTOR;
597
0
}
598
599
0
bool Tree::isMap() const {
600
0
  return m_type == Type::MAP;
601
0
}
602
603
0
bool Tree::isPairs() const {
604
0
  return m_type == Type::PAIRS;
605
0
}
606
607
734k
v_int64 Tree::getInteger() const {
608
734k
  if(m_type != Type::INTEGER) {
609
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getInteger()]: NOT an arbitrary INTEGER.");
610
0
  }
611
734k
  v_int64 result;
612
734k
  std::memcpy (&result, &m_data, sizeof(v_float64));
613
734k
  return result;
614
734k
}
615
616
8.39k
v_float64 Tree::getFloat() const {
617
8.39k
  if(m_type != Type::FLOAT) {
618
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getFloat()]: NOT an arbitrary FLOAT.");
619
0
  }
620
8.39k
  v_float64 result;
621
8.39k
  std::memcpy (&result, &m_data, sizeof(v_float64));
622
8.39k
  return result;
623
8.39k
}
624
625
1.73M
const type::String& Tree::getString() const {
626
1.73M
  if(m_type != Type::STRING) {
627
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getString()]: NOT a STRING.");
628
0
  }
629
1.73M
  auto data = reinterpret_cast<const type::String*>(m_data);
630
1.73M
  return *data;
631
1.73M
}
632
633
44.6k
const std::vector<Tree>& Tree::getVector() const {
634
44.6k
  if(m_type != Type::VECTOR) {
635
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getVector()]: NOT a VECTOR.");
636
0
  }
637
44.6k
  auto data = reinterpret_cast<const std::vector<Tree>*>(m_data);
638
44.6k
  return *data;
639
44.6k
}
640
641
18.3k
const TreeMap& Tree::getMap() const {
642
18.3k
  if(m_type != Type::MAP) {
643
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getMap()]: NOT a MAP.");
644
0
  }
645
18.3k
  auto data = reinterpret_cast<const TreeMap*>(m_data);
646
18.3k
  return *data;
647
18.3k
}
648
649
11.5k
const std::vector<std::pair<type::String, Tree>>& Tree::getPairs() const {
650
11.5k
  if(m_type != Type::PAIRS) {
651
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getPairs()]: NOT a PAIRS.");
652
0
  }
653
11.5k
  auto data = reinterpret_cast<const std::vector<std::pair<type::String, Tree>>*>(m_data);
654
11.5k
  return *data;
655
11.5k
}
656
657
167k
std::vector<Tree>& Tree::getVector() {
658
167k
  if(m_type == Type::UNDEFINED) {
659
0
    setVector({});
660
0
  }
661
167k
  if(m_type != Type::VECTOR) {
662
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getVector()]: NOT a VECTOR.");
663
0
  }
664
167k
  auto data = reinterpret_cast<std::vector<Tree>*>(m_data);
665
167k
  return *data;
666
167k
}
667
668
17.5k
TreeMap& Tree::getMap() {
669
17.5k
  if(m_type == Type::UNDEFINED) {
670
0
    setMap({});
671
0
  }
672
17.5k
  if(m_type != Type::MAP) {
673
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getMap()]: NOT a MAP.");
674
0
  }
675
17.5k
  auto data = reinterpret_cast<TreeMap*>(m_data);
676
17.5k
  return *data;
677
17.5k
}
678
679
0
std::vector<std::pair<type::String, Tree>>& Tree::getPairs() {
680
0
  if(m_type == Type::UNDEFINED) {
681
0
    setPairs({});
682
0
  }
683
0
  if(m_type != Type::PAIRS) {
684
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::getMap()]: NOT a PAIRS.");
685
0
  }
686
0
  auto data = reinterpret_cast<std::vector<std::pair<type::String, Tree>>*>(m_data);
687
0
  return *data;
688
0
}
689
690
0
Tree::Attributes& Tree::attributes() {
691
0
  return m_attributes;
692
0
}
693
694
0
const Tree::Attributes& Tree::attributes() const {
695
0
  return m_attributes;
696
0
}
697
698
0
type::String Tree::toString() const {
699
700
0
  stream::BufferOutputStream ss(128);
701
702
0
  switch (m_type) {
703
704
0
    case Type::UNDEFINED: {
705
0
      ss << "undefined";
706
0
      break;
707
0
    }
708
0
    case Type::NULL_VALUE: {
709
0
      ss << "null";
710
0
      break;
711
0
    }
712
713
0
    case Type::INTEGER: {
714
0
      ss << getInteger();
715
0
      break;
716
0
    }
717
0
    case Type::FLOAT: {
718
0
      ss << getFloat();
719
0
      break;
720
0
    }
721
722
0
    case Type::BOOL: {
723
0
      ss << getPrimitive<bool>();
724
0
      break;
725
0
    }
726
0
    case Type::INT_8: {
727
0
      ss << getPrimitive<v_int8>();
728
0
      break;
729
0
    }
730
0
    case Type::UINT_8: {
731
0
      ss << getPrimitive<v_uint8>();
732
0
      break;
733
0
    }
734
0
    case Type::INT_16: {
735
0
      ss << getPrimitive<v_int16>();
736
0
      break;
737
0
    }
738
0
    case Type::UINT_16: {
739
0
      ss << getPrimitive<v_uint16>();
740
0
      break;
741
0
    }
742
0
    case Type::INT_32: {
743
0
      ss << getPrimitive<v_int32 >();
744
0
      break;
745
0
    }
746
0
    case Type::UINT_32: {
747
0
      ss << getPrimitive<v_uint32>();
748
0
      break;
749
0
    }
750
0
    case Type::INT_64: {
751
0
      ss << getPrimitive<v_int64>();
752
0
      break;
753
0
    }
754
0
    case Type::UINT_64: {
755
0
      ss << getPrimitive<v_uint64>();
756
0
      break;
757
0
    }
758
0
    case Type::FLOAT_32: {
759
0
      ss << getPrimitive<v_float32>();
760
0
      break;
761
0
    }
762
0
    case Type::FLOAT_64: {
763
0
      ss << getPrimitive<v_float64>();
764
0
      break;
765
0
    }
766
0
    case Type::STRING: {
767
0
      ss << getString();
768
0
      break;
769
0
    }
770
771
0
    case Type::VECTOR: {
772
0
      ss << "<vector>";
773
0
      break;
774
0
    }
775
0
    case Type::MAP: {
776
0
      ss << "<map>";
777
0
      break;
778
0
    }
779
0
    case Type::PAIRS: {
780
0
      ss << "<pairs>";
781
0
      break;
782
0
    }
783
784
0
    default:
785
0
      break;
786
0
  }
787
788
0
  return ss.toString();
789
790
0
}
791
792
0
type::String Tree::debugPrint(v_uint32 indent0, v_uint32 indentDelta, bool firstLineIndent) const {
793
794
0
  stream::BufferOutputStream ss;
795
0
  for(v_uint32 i = 0; i < indent0; i ++) {
796
0
    ss << " ";
797
0
  }
798
0
  type::String indentStr0 = ss.toString();
799
800
0
  ss.setCurrentPosition(0);
801
0
  for(v_uint32 i = 0; i < indentDelta; i ++) {
802
0
    ss << " ";
803
0
  }
804
0
  type::String indentDeltaStr = ss.toString();
805
806
0
  ss.setCurrentPosition(0);
807
0
  if(firstLineIndent) {
808
0
    ss << indentStr0;
809
0
  }
810
811
812
0
  switch (m_type) {
813
814
0
    case Type::UNDEFINED: {
815
0
      ss << "undefined";
816
0
      break;
817
0
    }
818
0
    case Type::NULL_VALUE: {
819
0
      ss << "null";
820
0
      break;
821
0
    }
822
823
0
    case Type::INTEGER: {
824
0
      ss << getInteger() << " (integer)";
825
0
      break;
826
0
    }
827
0
    case Type::FLOAT: {
828
0
      ss << getFloat() << " (float)";
829
0
      break;
830
0
    }
831
832
0
    case Type::BOOL: {
833
0
      ss << getPrimitive<bool>() << " (bool)";
834
0
      break;
835
0
    }
836
0
    case Type::INT_8: {
837
0
      ss << getPrimitive<v_int8>() << " (int_8)";
838
0
      break;
839
0
    }
840
841
0
    case Type::UINT_8: {
842
0
      ss << getPrimitive<v_uint8>() << " (uint_8)";
843
0
      break;
844
0
    }
845
0
    case Type::INT_16: {
846
0
      ss << getPrimitive<v_int16>() << " (int_16)";
847
0
      break;
848
0
    }
849
0
    case Type::UINT_16: {
850
0
      ss << getPrimitive<v_uint16>() << " (uint_16)";
851
0
      break;
852
0
    }
853
0
    case Type::INT_32: {
854
0
      ss << getPrimitive<v_int32 >() << " (int_32)";
855
0
      break;
856
0
    }
857
0
    case Type::UINT_32: {
858
0
      ss << getPrimitive<v_uint32>() << " (uint_32)";
859
0
      break;
860
0
    }
861
0
    case Type::INT_64: {
862
0
      ss << getPrimitive<v_int64>() << " (int_64)";
863
0
      break;
864
0
    }
865
0
    case Type::UINT_64: {
866
0
      ss << getPrimitive<v_uint64>() << " (uint_64)";
867
0
      break;
868
0
    }
869
0
    case Type::FLOAT_32: {
870
0
      ss << getPrimitive<v_float32>() << " (float_32)";
871
0
      break;
872
0
    }
873
0
    case Type::FLOAT_64: {
874
0
      ss << getPrimitive<v_float64>() << " (float_64)";
875
0
      break;
876
0
    }
877
0
    case Type::STRING: {
878
0
      ss << "'" << getString() << "'";
879
0
      break;
880
0
    }
881
882
0
    case Type::VECTOR: {
883
0
      ss << "VECTOR [\n";
884
0
      auto& vector = getVector();
885
0
      for(auto& v : vector) {
886
0
        ss << v.debugPrint(indent0 + indentDelta, indentDelta) << "\n";
887
0
      }
888
0
      ss << indentStr0 << "]";
889
0
      break;
890
0
    }
891
0
    case Type::MAP: {
892
0
      ss << "MAP {\n";
893
0
      auto& map = getMap();
894
0
      for(v_uint32 i = 0; i < map.size(); i ++) {
895
0
        const auto& node = map[i];
896
0
        ss << indentStr0 << indentDeltaStr << node.first << ": " << node.second.get().debugPrint(indent0 + indentDelta, indentDelta, false) << "\n";
897
0
      }
898
0
      ss << indentStr0 << "}";
899
0
      break;
900
0
    }
901
0
    case Type::PAIRS: {
902
0
      ss << "PAIRS {\n";
903
0
      auto& pairs = getPairs();
904
0
      for(auto& node : pairs) {
905
0
        ss << indentStr0 << indentDeltaStr << node.first << ": " << node.second.debugPrint(indent0 + indentDelta, indentDelta, false) << "\n";
906
0
      }
907
0
      ss << indentStr0 << "}";
908
0
      break;
909
0
    }
910
911
0
    default:
912
0
      break;
913
0
  }
914
915
0
  return ss.toString();
916
917
0
}
918
919
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
920
// TreeMap
921
922
0
TreeMap::TreeMap(const TreeMap& other) {
923
0
  operator=(other);
924
0
}
925
926
21.5k
TreeMap::TreeMap(TreeMap&& other) noexcept {
927
21.5k
  operator=(std::move(other));
928
21.5k
}
929
930
0
TreeMap& TreeMap::operator = (const TreeMap& other) {
931
0
  m_map = other.m_map;
932
0
  m_order = other.m_order;
933
0
  for(auto & po : m_order){
934
0
    po.second = &m_map.at(po.first.lock());
935
0
  }
936
0
  return *this;
937
0
}
938
939
21.5k
TreeMap& TreeMap::operator = (TreeMap&& other) noexcept {
940
21.5k
  m_map = std::move(other.m_map);
941
21.5k
  m_order = std::move(other.m_order);
942
21.5k
  for(auto& p : m_order) {
943
0
    p.second = &m_map.at(p.first.lock());
944
0
  }
945
21.5k
  return *this;
946
21.5k
}
947
948
188k
Tree& TreeMap::operator [] (const type::String& key) {
949
188k
  auto it = m_map.find(key);
950
188k
  if(it == m_map.end()) {
951
157k
    auto& result = m_map[key];
952
157k
    m_order.emplace_back(key.getPtr(), &result);
953
157k
    return result;
954
157k
  }
955
31.5k
  return it->second;
956
188k
}
957
958
0
const Tree& TreeMap::operator [] (const type::String& key) const {
959
0
  auto it = m_map.find(key);
960
0
  if(it == m_map.end()) {
961
0
    throw std::runtime_error("[oatpp::data::mapping::Tree::TreeMap::operator[]]: const operator[] can't add items.");
962
0
  }
963
0
  return it->second;
964
0
}
965
966
0
std::pair<type::String, std::reference_wrapper<Tree>> TreeMap::operator [] (v_uint64 index) {
967
0
  auto& item = m_order.at(index);
968
0
  return {item.first.lock(), *item.second};
969
0
}
970
971
125k
std::pair<type::String, std::reference_wrapper<const Tree>> TreeMap::operator [] (v_uint64 index) const {
972
125k
  auto& item = m_order.at(index);
973
125k
  return {item.first.lock(), *item.second};
974
125k
}
975
976
14.4k
v_uint64 TreeMap::size() const {
977
14.4k
  return m_map.size();
978
14.4k
}
979
980
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
981
// TreeChildrenOperator
982
983
TreeChildrenOperator::TreeChildrenOperator(Tree& tree)
984
23.7k
  : TreeChildrenOperator(const_cast<const Tree&>(tree))
985
23.7k
{
986
23.7k
  m_const = false;
987
23.7k
}
988
989
TreeChildrenOperator::TreeChildrenOperator(const Tree& tree)
990
51.4k
  : m_vector(nullptr)
991
51.4k
  , m_map(nullptr)
992
51.4k
  , m_pairs(nullptr)
993
51.4k
{
994
51.4k
  m_const = true;
995
51.4k
  if(tree.getType() == Tree::Type::VECTOR) {
996
30.5k
    m_type = VECTOR;
997
30.5k
    m_vector = std::addressof(tree.getVector());
998
30.5k
  } else if(tree.getType() == Tree::Type::MAP) {
999
14.4k
    m_type = MAP;
1000
14.4k
    m_map = std::addressof(tree.getMap());
1001
14.4k
  } else if(tree.getType() == Tree::Type::PAIRS) {
1002
5.76k
    m_type = PAIRS;
1003
5.76k
    m_pairs = std::addressof(tree.getPairs());
1004
5.76k
  } else {
1005
679
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::TreeChildrenOperator()]: Node type is NOT suppoerted");
1006
679
  }
1007
51.4k
}
1008
1009
0
std::pair<type::String, Tree*> TreeChildrenOperator::getPair(v_uint64 index) {
1010
0
  if(m_const) {
1011
0
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getPair()]: Can't operate on CONST tree node");
1012
0
  }
1013
0
  switch (m_type) {
1014
0
    case VECTOR: break;
1015
0
    case MAP: {
1016
0
      const auto& p = (*const_cast<TreeMap*>(m_map))[index];
1017
0
      return {p.first, std::addressof(p.second.get())};
1018
0
    }
1019
0
    case PAIRS: {
1020
0
      auto& p = const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs)->at(index);
1021
0
      return {p.first, &p.second};
1022
0
    }
1023
0
    default:
1024
0
      break;
1025
0
  }
1026
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getPair()]: Node type doesn't support pairs");
1027
0
}
1028
1029
43.5k
std::pair<type::String, const Tree*> TreeChildrenOperator::getPair(v_uint64 index) const {
1030
43.5k
  switch (m_type) {
1031
15
    case VECTOR: break;
1032
43.5k
    case MAP: {
1033
43.5k
      const auto& p = (*m_map)[index];
1034
43.5k
      return {p.first, std::addressof(p.second.get())};
1035
0
    }
1036
0
    case PAIRS: {
1037
0
      auto& p = (*m_pairs)[index];
1038
0
      return {p.first, &p.second};
1039
0
    }
1040
0
    default:
1041
0
      break;
1042
43.5k
  }
1043
15
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getPair()]: Node type doesn't support pairs");
1044
43.5k
}
1045
1046
0
Tree* TreeChildrenOperator::getItem(v_uint64 index) {
1047
0
  if(m_const) {
1048
0
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getItem()]: Can't operate on CONST tree node");
1049
0
  }
1050
0
  switch (m_type) {
1051
0
    case VECTOR: return std::addressof(const_cast<std::vector<Tree>*>(m_vector)->at(index));
1052
0
    case MAP: return std::addressof((*const_cast<TreeMap*>(m_map))[index].second.get());
1053
0
    case PAIRS: return &const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs)->at(index).second;
1054
0
    default:
1055
0
      break;
1056
0
  }
1057
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getItem()]: Invalid iterator type");
1058
0
}
1059
1060
1.60M
const Tree* TreeChildrenOperator::getItem(v_uint64 index) const {
1061
1.60M
  switch (m_type) {
1062
1.60M
    case VECTOR: return std::addressof(m_vector->at(index));
1063
195
    case MAP: return std::addressof((*m_map)[index].second.get());
1064
0
    case PAIRS: return &m_pairs->at(index).second;
1065
0
    default:
1066
0
      break;
1067
1.60M
  }
1068
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getItem()]: Invalid operator type");
1069
1.60M
}
1070
1071
0
Tree* TreeChildrenOperator::putPair(const type::String& key, const Tree& tree) {
1072
0
  if(m_const) {
1073
0
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Can't operate on CONST tree node");
1074
0
  }
1075
0
  switch (m_type) {
1076
0
    case VECTOR: break;
1077
0
    case MAP: {
1078
0
      auto& node = (*const_cast<TreeMap*>(m_map))[key];
1079
0
      node = tree;
1080
0
      return std::addressof(node);
1081
0
    }
1082
0
    case PAIRS: {
1083
0
      auto& pairs = *const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs);
1084
0
      pairs.emplace_back(key, tree);
1085
0
      auto& p = pairs.at(pairs.size() - 1);
1086
0
      return std::addressof(p.second);
1087
0
    }
1088
0
    default:
1089
0
      break;
1090
0
  }
1091
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Node type doesn't support pairs");
1092
0
}
1093
1094
97.6k
Tree* TreeChildrenOperator::putPair(const type::String& key, Tree&& tree) {
1095
97.6k
  if(m_const) {
1096
0
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Can't operate on CONST tree node");
1097
0
  }
1098
97.6k
  switch (m_type) {
1099
0
    case VECTOR: break;
1100
81.6k
    case MAP: {
1101
81.6k
      auto& node = (*const_cast<TreeMap*>(m_map))[key];
1102
81.6k
      node = std::move(tree);
1103
81.6k
      return std::addressof(node);
1104
0
    }
1105
16.0k
    case PAIRS: {
1106
16.0k
      auto& pairs = *const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs);
1107
16.0k
      pairs.emplace_back(key, std::move(tree));
1108
16.0k
      auto& p = pairs.at(pairs.size() - 1);
1109
16.0k
      return std::addressof(p.second);
1110
0
    }
1111
0
    default:
1112
0
      break;
1113
97.6k
  }
1114
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Node type doesn't support pairs");
1115
97.6k
}
1116
1117
0
Tree* TreeChildrenOperator::putItem(const Tree& tree) {
1118
0
  if(m_const) {
1119
0
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Can't operate on CONST tree node");
1120
0
  }
1121
0
  switch (m_type) {
1122
0
    case VECTOR: {
1123
0
      auto& vector = *const_cast<std::vector<Tree>*>(m_vector);
1124
0
      vector.push_back(tree);
1125
0
      return std::addressof(vector.at(vector.size() - 1));
1126
0
    }
1127
0
    case MAP:
1128
0
    case PAIRS:
1129
0
    default:
1130
0
      break;
1131
0
  }
1132
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Invalid iterator type");
1133
0
}
1134
1135
1.53M
Tree* TreeChildrenOperator::putItem(Tree&& tree) {
1136
1.53M
  if(m_const) {
1137
0
    throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Can't operate on CONST tree node");
1138
0
  }
1139
1.53M
  switch (m_type) {
1140
1.53M
    case VECTOR: {
1141
1.53M
      auto& vector = *const_cast<std::vector<Tree>*>(m_vector);
1142
1.53M
      vector.emplace_back(std::move(tree));
1143
1.53M
      return std::addressof(vector.at(vector.size() - 1));
1144
0
    }
1145
0
    case MAP:
1146
0
    case PAIRS:
1147
0
    default:
1148
0
      break;
1149
1.53M
  }
1150
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Invalid iterator type");
1151
1.53M
}
1152
1153
26.9k
v_uint64 TreeChildrenOperator::size() const {
1154
26.9k
  switch (m_type) {
1155
16.4k
    case VECTOR: return m_vector->size();
1156
10.5k
    case MAP: return m_map->size();
1157
0
    case PAIRS: return m_pairs->size();
1158
0
    default:
1159
0
      break;
1160
26.9k
  }
1161
0
  throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::size()]: Invalid operator type");
1162
26.9k
}
1163
1164
}}}