@@ -58,12 +58,12 @@ Deserializer::Deserializer(const std::shared_ptr<Config>& config)
58
58
// ----------------
59
59
// Collections
60
60
61
- setDeserializerMethod (data::mapping::type::__class::AbstractVector::CLASS_ID, &Deserializer::deserializeArray<oatpp::AbstractVector> );
62
- setDeserializerMethod (data::mapping::type::__class::AbstractList::CLASS_ID, &Deserializer::deserializeArray<oatpp::AbstractList> );
63
- setDeserializerMethod (data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Deserializer::deserializeArray<oatpp::AbstractUnorderedSet> );
61
+ setDeserializerMethod (data::mapping::type::__class::AbstractVector::CLASS_ID, &Deserializer::deserializeCollection );
62
+ setDeserializerMethod (data::mapping::type::__class::AbstractList::CLASS_ID, &Deserializer::deserializeCollection );
63
+ setDeserializerMethod (data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Deserializer::deserializeCollection );
64
64
65
- setDeserializerMethod (data::mapping::type::__class::AbstractPairList::CLASS_ID, &Deserializer::deserializeKeyValue<oatpp::AbstractFields> );
66
- setDeserializerMethod (data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Deserializer::deserializeKeyValue<oatpp::AbstractUnorderedFields> );
65
+ setDeserializerMethod (data::mapping::type::__class::AbstractPairList::CLASS_ID, &Deserializer::deserializeMap );
66
+ setDeserializerMethod (data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Deserializer::deserializeMap );
67
67
68
68
69
69
// ----------------
@@ -80,11 +80,10 @@ Deserializer::Deserializer(const std::shared_ptr<Config>& config)
80
80
81
81
void Deserializer::setDeserializerMethod (const data::mapping::type::ClassId& classId, DeserializerMethod method) {
82
82
const v_uint32 id = classId.id ;
83
- if (id < m_methods.size ()) {
84
- m_methods[id] = method;
85
- } else {
86
- throw std::runtime_error (" [oatpp::mongo::bson::mapping::Deserializer::setDeserializerMethod()]: Error. Unknown classId" );
83
+ if (id >= m_methods.size ()) {
84
+ m_methods.resize (id + 1 , nullptr );
87
85
}
86
+ m_methods[id] = method;
88
87
}
89
88
90
89
void Deserializer::skipCString (parser::Caret& caret) {
@@ -386,6 +385,167 @@ oatpp::Void Deserializer::deserializeEnum(Deserializer* deserializer,
386
385
387
386
}
388
387
388
+ oatpp::Void Deserializer::deserializeCollection (Deserializer* deserializer,
389
+ parser::Caret& caret,
390
+ const Type* const type,
391
+ v_char8 bsonTypeCode)
392
+ {
393
+
394
+ switch (bsonTypeCode) {
395
+
396
+ case TypeCode::NULL_VALUE:
397
+ return oatpp::Void (type);
398
+
399
+ case TypeCode::DOCUMENT_ROOT:
400
+ case TypeCode::DOCUMENT_EMBEDDED:
401
+ case TypeCode::DOCUMENT_ARRAY:
402
+ {
403
+
404
+ v_int32 docSize = Utils::readInt32 (caret);
405
+ if (docSize - 4 + caret.getPosition () > caret.getDataSize () || docSize < 4 ) {
406
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeCollection()]: Error. Invalid document size." );
407
+ return nullptr ;
408
+ }
409
+
410
+ parser::Caret innerCaret (caret.getCurrData (), docSize - 4 );
411
+
412
+ auto dispatcher = static_cast <const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(type->polymorphicDispatcher );
413
+ auto collection = dispatcher->createObject ();
414
+
415
+ const Type* itemType = dispatcher->getItemType ();
416
+ v_int32 expectedIndex = 0 ;
417
+ while (innerCaret.canContinue () && innerCaret.getPosition () < innerCaret.getDataSize () - 1 ) {
418
+
419
+ v_char8 valueTypeCode;
420
+ auto key = Utils::readKey (innerCaret, valueTypeCode);
421
+ if (innerCaret.hasError ()){
422
+ caret.inc (innerCaret.getPosition ());
423
+ caret.setError (innerCaret.getErrorMessage (), innerCaret.getErrorCode ());
424
+ return nullptr ;
425
+ }
426
+
427
+ bool success;
428
+ v_int32 keyIntValue = utils::conversion::strToInt32 (key, success);
429
+ if (!success || keyIntValue != expectedIndex) {
430
+ caret.inc (innerCaret.getPosition ());
431
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeCollection()]: Error. Array invalid index value. Looks like it's not an array." );
432
+ return nullptr ;
433
+ }
434
+
435
+ auto item = deserializer->deserialize (innerCaret, itemType, valueTypeCode);
436
+ if (innerCaret.hasError ()){
437
+ caret.inc (innerCaret.getPosition ());
438
+ caret.setError (innerCaret.getErrorMessage (), innerCaret.getErrorCode ());
439
+ return nullptr ;
440
+ }
441
+
442
+ dispatcher->addItem (collection, item);
443
+ ++ expectedIndex;
444
+
445
+ }
446
+
447
+ if (!innerCaret.canContinueAtChar (0 , 1 )){
448
+ caret.inc (innerCaret.getPosition ());
449
+ if (innerCaret.hasError ()) {
450
+ caret.setError (innerCaret.getErrorMessage (), innerCaret.getErrorCode ());
451
+ } else {
452
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeCollection()]: Error. '\\ 0' - expected" );
453
+ }
454
+ return nullptr ;
455
+ }
456
+
457
+ if (innerCaret.getPosition () != innerCaret.getDataSize ()) {
458
+ caret.inc (innerCaret.getPosition ());
459
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeCollection()]: Error. Document parsing failed." );
460
+ }
461
+
462
+ caret.inc (innerCaret.getPosition ());
463
+ return collection;
464
+
465
+ }
466
+
467
+ default :
468
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeCollection()]: Error. Invalid type code." );
469
+ return nullptr ;
470
+
471
+ }
472
+
473
+ }
474
+
475
+ oatpp::Void Deserializer::deserializeMap (Deserializer* deserializer,
476
+ parser::Caret& caret,
477
+ const Type* const type,
478
+ v_char8 bsonTypeCode)
479
+ {
480
+
481
+ switch (bsonTypeCode) {
482
+
483
+ case TypeCode::NULL_VALUE:
484
+ return oatpp::Void (type);
485
+
486
+ case TypeCode::DOCUMENT_ROOT:
487
+ case TypeCode::DOCUMENT_EMBEDDED:
488
+ case TypeCode::DOCUMENT_ARRAY:
489
+ {
490
+
491
+ v_int32 docSize = Utils::readInt32 (caret);
492
+ if (docSize - 4 + caret.getPosition () > caret.getDataSize () || docSize < 4 ) {
493
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeMap()]: Error. Invalid document size." );
494
+ return nullptr ;
495
+ }
496
+
497
+ parser::Caret innerCaret (caret.getCurrData (), docSize - 4 );
498
+
499
+ auto dispatcher = static_cast <const data::mapping::type::__class::Map::PolymorphicDispatcher*>(type->polymorphicDispatcher );
500
+ auto map = dispatcher->createObject ();
501
+
502
+ const Type* keyType = dispatcher->getKeyType ();
503
+ if (keyType->classId .id != oatpp::data::mapping::type::__class::String::CLASS_ID.id ){
504
+ throw std::runtime_error (" [oatpp::mongo::bson::mapping::Deserializer::deserializeMap()]: Invalid bson map key. Key should be String" );
505
+ }
506
+
507
+ const Type* valueType = dispatcher->getValueType ();
508
+ while (innerCaret.canContinue () && innerCaret.getPosition () < innerCaret.getDataSize () - 1 ) {
509
+
510
+ v_char8 valueTypeCode;
511
+ auto key = Utils::readKey (innerCaret, valueTypeCode);
512
+ if (innerCaret.hasError ()){
513
+ caret.inc (innerCaret.getPosition ());
514
+ caret.setError (innerCaret.getErrorMessage (), innerCaret.getErrorCode ());
515
+ return nullptr ;
516
+ }
517
+
518
+ dispatcher->addItem (map, key, deserializer->deserialize (innerCaret, valueType, valueTypeCode));
519
+
520
+ }
521
+
522
+ if (!innerCaret.canContinueAtChar (0 , 1 )){
523
+ caret.inc (innerCaret.getPosition ());
524
+ if (innerCaret.hasError ()) {
525
+ caret.setError (innerCaret.getErrorMessage (), innerCaret.getErrorCode ());
526
+ } else {
527
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeMap()]: Error. '\\ 0' - expected" );
528
+ }
529
+ return nullptr ;
530
+ }
531
+
532
+ if (innerCaret.getPosition () != innerCaret.getDataSize ()) {
533
+ caret.inc (innerCaret.getPosition ());
534
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeMap()]: Error. Document parsing failed." );
535
+ }
536
+
537
+ caret.inc (innerCaret.getPosition ());
538
+ return oatpp::Void (map.getPtr (), map.getValueType ());
539
+
540
+ }
541
+
542
+ default :
543
+ caret.setError (" [oatpp::mongo::bson::mapping::Deserializer::deserializeMap()]: Error. Invalid type code." );
544
+ return nullptr ;
545
+ }
546
+
547
+ }
548
+
389
549
oatpp::Void Deserializer::deserializeObject (Deserializer* deserializer,
390
550
parser::Caret& caret,
391
551
const Type* const type,
@@ -414,6 +574,7 @@ oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
414
574
auto object = dispatcher->createObject ();
415
575
const auto & fieldsMap = dispatcher->getProperties ()->getMap ();
416
576
577
+ std::vector<PolymorphData> polymorphs;
417
578
while (innerCaret.canContinue () && innerCaret.getPosition () < innerCaret.getDataSize () - 1 ) {
418
579
419
580
v_char8 valueType;
@@ -428,7 +589,22 @@ oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
428
589
if (fieldIterator != fieldsMap.end ()){
429
590
430
591
auto field = fieldIterator->second ;
431
- field->set (static_cast <oatpp::BaseObject*>(object.get ()), deserializer->deserialize (innerCaret, field->type , valueType));
592
+ if (field->info .typeSelector && field->type == oatpp::Any::Class::getType ()) {
593
+ auto label = innerCaret.putLabel ();
594
+ skipElement (innerCaret, valueType);
595
+ if (innerCaret.hasError ()){
596
+ caret.inc (innerCaret.getPosition ());
597
+ caret.setError (innerCaret.getErrorMessage (), innerCaret.getErrorCode ());
598
+ return nullptr ;
599
+ }
600
+ PolymorphData polymorphData;
601
+ polymorphData.field = field;
602
+ polymorphData.unparsedData = label.toString ();
603
+ polymorphData.valueType = valueType;
604
+ polymorphs.push_back (polymorphData); // store polymorphs for later processing.
605
+ } else {
606
+ field->set (static_cast <oatpp::BaseObject *>(object.get ()),deserializer->deserialize (innerCaret, field->type , valueType));
607
+ }
432
608
433
609
} else if (deserializer->getConfig ()->allowUnknownFields ) {
434
610
skipElement (innerCaret, valueType);
@@ -461,6 +637,15 @@ oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
461
637
}
462
638
463
639
caret.inc (innerCaret.getPosition ());
640
+
641
+ for (auto & p : polymorphs) {
642
+ parser::Caret polyCaret (p.unparsedData );
643
+ auto selectedType = p.field ->info .typeSelector ->selectType (static_cast <oatpp::BaseObject *>(object.get ()));
644
+ auto value = deserializer->deserialize (polyCaret, selectedType, p.valueType );
645
+ oatpp::Any any (value);
646
+ p.field ->set (static_cast <oatpp::BaseObject *>(object.get ()), oatpp::Void (any.getPtr (), p.field ->type ));
647
+ }
648
+
464
649
return object;
465
650
466
651
}
0 commit comments