@@ -66,9 +66,9 @@ void Serializer::setSerializerMethods() {
6666
6767 setSerializerMethod (data::mapping::type::__class::AbstractEnum::CLASS_ID, &Serializer::serializeEnum);
6868
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);
7272
7373 // //
7474
@@ -464,45 +464,29 @@ void Serializer::serializeUuid(const Serializer* _this, OutputData& outData, con
464464
465465const oatpp::Type* Serializer::getArrayItemTypeAndDimensions (const oatpp::Void& polymorph, std::vector<v_int32>& dimensions) {
466466
467- void * currObj = polymorph.get ();
468- const oatpp::Type* currType = polymorph.getValueType ();
467+ oatpp::Void curr = polymorph;
469468
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 ) {
474470
475- if (currObj == nullptr ) {
471+ if (curr == nullptr ) {
476472 throw std::runtime_error (" [oatpp::postgresql::mapping::Serializer::getArrayItemTypeAndDimensions()]: Error. "
477473 " The nested container can't be null." );
478474 }
479475
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);
498479
480+ if (size > 0 ) {
481+ auto iterator = dispatcher->beginIteration (curr);
482+ curr = iterator->get ();
483+ } else {
484+ curr = nullptr ;
499485 }
500486
501- currType = *currType->params .begin ();
502-
503487 }
504488
505- return currType ;
489+ return curr. getValueType () ;
506490
507491}
508492
@@ -513,20 +497,84 @@ void Serializer::serializeSubArray(data::stream::ConsistentOutputStream* stream,
513497{
514498
515499 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 ();
516506
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+ }
519530
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 ()) {
522533
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 () );
525536
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);
526555 }
527556
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 );
530578
531579}
532580
0 commit comments