@@ -66,9 +66,9 @@ void Serializer::setSerializerMethods() {
66
66
67
67
setSerializerMethod (data::mapping::type::__class::AbstractEnum::CLASS_ID, &Serializer::serializeEnum);
68
68
69
- setSerializerMethod (data::mapping::type::__class::AbstractVector::CLASS_ID, &Serializer::serializeArray<oatpp::AbstractVector> );
70
- setSerializerMethod (data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeArray<oatpp::AbstractList> );
71
- setSerializerMethod (data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Serializer::serializeArray<oatpp::AbstractUnorderedSet> );
69
+ setSerializerMethod (data::mapping::type::__class::AbstractVector::CLASS_ID, &Serializer::serializeArray);
70
+ setSerializerMethod (data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeArray);
71
+ setSerializerMethod (data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Serializer::serializeArray);
72
72
73
73
// //
74
74
@@ -464,45 +464,29 @@ void Serializer::serializeUuid(const Serializer* _this, OutputData& outData, con
464
464
465
465
const oatpp::Type* Serializer::getArrayItemTypeAndDimensions (const oatpp::Void& polymorph, std::vector<v_int32>& dimensions) {
466
466
467
- void * currObj = polymorph.get ();
468
- const oatpp::Type* currType = polymorph.getValueType ();
467
+ oatpp::Void curr = polymorph;
469
468
470
- while (currType->classId .id == oatpp::AbstractVector::Class::CLASS_ID.id ||
471
- currType->classId .id == oatpp::AbstractList::Class::CLASS_ID.id ||
472
- currType->classId .id == oatpp::AbstractUnorderedSet::Class::CLASS_ID.id )
473
- {
469
+ while (curr.getValueType ()->isCollection ) {
474
470
475
- if (currObj == nullptr ) {
471
+ if (curr == nullptr ) {
476
472
throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::getArrayItemTypeAndDimensions()]: Error. "
477
473
" The nested container can't be null." );
478
474
}
479
475
480
- if (currType->classId .id == oatpp::AbstractVector::Class::CLASS_ID.id ) {
481
-
482
- auto c = static_cast <std::vector<oatpp::Void>*>(currObj);
483
- dimensions.push_back (c->size ());
484
- currObj = (c->size () > 0 ) ? (*c)[0 ].get () : nullptr ;
485
-
486
- } else if (currType->classId .id == oatpp::AbstractList::Class::CLASS_ID.id ) {
487
-
488
- auto c = static_cast <std::list<oatpp::Void>*>(currObj);
489
- dimensions.push_back (c->size ());
490
- currObj = (c->size () > 0 ) ? c->front ().get () : nullptr ;
491
-
492
-
493
- } else if (currType->classId .id == oatpp::AbstractUnorderedSet::Class::CLASS_ID.id ) {
494
-
495
- auto c = static_cast <std::unordered_set<oatpp::Void>*>(currObj);
496
- dimensions.push_back (c->size ());
497
- currObj = (c->size () > 0 ) ? c->begin ()->get () : nullptr ;
476
+ auto dispatcher = static_cast <const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(curr.getValueType ()->polymorphicDispatcher );
477
+ auto size = dispatcher->getCollectionSize (curr);
478
+ dimensions.push_back (size);
498
479
480
+ if (size > 0 ) {
481
+ auto iterator = dispatcher->beginIteration (curr);
482
+ curr = iterator->get ();
483
+ } else {
484
+ curr = nullptr ;
499
485
}
500
486
501
- currType = *currType->params .begin ();
502
-
503
487
}
504
488
505
- return currType ;
489
+ return curr. getValueType () ;
506
490
507
491
}
508
492
@@ -513,20 +497,84 @@ void Serializer::serializeSubArray(data::stream::ConsistentOutputStream* stream,
513
497
{
514
498
515
499
const oatpp::Type* type = polymorph.getValueType ();
500
+ if (!type->isCollection ) {
501
+ throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::serializeSubArray()]: Error. Unknown collection type." );
502
+ }
503
+
504
+ auto dispatcher = static_cast <const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(type->polymorphicDispatcher );
505
+ const oatpp::Type* itemType = dispatcher->getItemType ();
516
506
517
- if (data::mapping::type::__class::AbstractVector::CLASS_ID.id == type->classId .id ) {
518
- return serializeSubArray<oatpp::AbstractVector>(stream, polymorph, meta, dimension);
507
+ if (dimension < meta.dimensions .size () - 1 ) {
508
+
509
+ auto size = meta.dimensions [dimension];
510
+
511
+ if (dispatcher->getCollectionSize (polymorph) != size) {
512
+ throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::serializeSubArray()]. Error. "
513
+ " All nested arrays must be of the same size." );
514
+ }
515
+
516
+ auto iterator = dispatcher->beginIteration (polymorph);
517
+ while (!iterator->finished ()) {
518
+ serializeSubArray (stream, iterator->get (), meta, dimension + 1 );
519
+ iterator->next ();
520
+ }
521
+
522
+ } else if (dimension == meta.dimensions .size () - 1 ) {
523
+
524
+ auto size = meta.dimensions [dimension];
525
+
526
+ if (dispatcher->getCollectionSize (polymorph) != size) {
527
+ throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::serializeSubArray()]. Error. "
528
+ " All nested arrays must be of the same size." );
529
+ }
519
530
520
- } else if (data::mapping::type::__class::AbstractList::CLASS_ID. id == type-> classId . id ) {
521
- return serializeSubArray<oatpp::AbstractList>(stream, polymorph, meta, dimension);
531
+ auto iterator = dispatcher-> beginIteration (polymorph);
532
+ while (!iterator-> finished ()) {
522
533
523
- } else if (data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID. id == type-> classId . id ) {
524
- return serializeSubArray<oatpp::AbstractUnorderedSet>(stream, polymorph, meta, dimension );
534
+ OutputData data;
535
+ meta. _this -> serialize (data, iterator-> get () );
525
536
537
+ v_int32 itemSize = htonl (data.dataSize );
538
+ stream->writeSimple (&itemSize, sizeof (v_int32));
539
+
540
+ if (data.data != nullptr ) {
541
+ stream->writeSimple (data.data , data.dataSize );
542
+ }
543
+
544
+ iterator->next ();
545
+ }
546
+
547
+ }
548
+
549
+ }
550
+
551
+ void Serializer::serializeArray (const Serializer* _this, OutputData& outData, const oatpp::Void& polymorph) {
552
+
553
+ if (!polymorph) {
554
+ serNull (outData);
526
555
}
527
556
528
- throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::serializeSubArray()]: "
529
- " Error. Unknown 1D collection type." );
557
+ ArraySerializationMeta meta;
558
+ meta._this = _this;
559
+ const oatpp::Type* itemType = getArrayItemTypeAndDimensions (polymorph, meta.dimensions );
560
+
561
+ if (meta.dimensions .empty ()) {
562
+ throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::serializeArray()]: Error. "
563
+ " Invalid array." );
564
+ }
565
+
566
+ data::stream::BufferOutputStream stream;
567
+ ArrayUtils::writeArrayHeader (&stream, _this->getTypeOid (itemType), meta.dimensions );
568
+
569
+ serializeSubArray (&stream, polymorph, meta, 0 );
570
+
571
+ outData.oid = _this->getArrayTypeOid (itemType);
572
+ outData.dataSize = stream.getCurrentPosition ();
573
+ outData.dataBuffer .reset (new char [outData.dataSize ]);
574
+ outData.data = outData.dataBuffer .get ();
575
+ outData.dataFormat = 1 ;
576
+
577
+ std::memcpy (outData.data , stream.getData (), outData.dataSize );
530
578
531
579
}
532
580
0 commit comments