Skip to content

Commit

Permalink
update Serializer to the latest oatpp API
Browse files Browse the repository at this point in the history
  • Loading branch information
lganzzzo committed Nov 8, 2021
1 parent 52beff8 commit 3bc13cb
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 122 deletions.
126 changes: 87 additions & 39 deletions src/oatpp-postgresql/mapping/Serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ void Serializer::setSerializerMethods() {

setSerializerMethod(data::mapping::type::__class::AbstractEnum::CLASS_ID, &Serializer::serializeEnum);

setSerializerMethod(data::mapping::type::__class::AbstractVector::CLASS_ID, &Serializer::serializeArray<oatpp::AbstractVector>);
setSerializerMethod(data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeArray<oatpp::AbstractList>);
setSerializerMethod(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Serializer::serializeArray<oatpp::AbstractUnorderedSet>);
setSerializerMethod(data::mapping::type::__class::AbstractVector::CLASS_ID, &Serializer::serializeArray);
setSerializerMethod(data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeArray);
setSerializerMethod(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Serializer::serializeArray);

////

Expand Down Expand Up @@ -464,45 +464,29 @@ void Serializer::serializeUuid(const Serializer* _this, OutputData& outData, con

const oatpp::Type* Serializer::getArrayItemTypeAndDimensions(const oatpp::Void& polymorph, std::vector<v_int32>& dimensions) {

void* currObj = polymorph.get();
const oatpp::Type* currType = polymorph.getValueType();
oatpp::Void curr = polymorph;

while(currType->classId.id == oatpp::AbstractVector::Class::CLASS_ID.id ||
currType->classId.id == oatpp::AbstractList::Class::CLASS_ID.id ||
currType->classId.id == oatpp::AbstractUnorderedSet::Class::CLASS_ID.id)
{
while(curr.getValueType()->isCollection) {

if(currObj == nullptr) {
if(curr == nullptr) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::getArrayItemTypeAndDimensions()]: Error. "
"The nested container can't be null.");
}

if(currType->classId.id == oatpp::AbstractVector::Class::CLASS_ID.id) {

auto c = static_cast<std::vector<oatpp::Void>*>(currObj);
dimensions.push_back(c->size());
currObj = (c->size() > 0) ? (*c)[0].get() : nullptr;

} else if(currType->classId.id == oatpp::AbstractList::Class::CLASS_ID.id) {

auto c = static_cast<std::list<oatpp::Void>*>(currObj);
dimensions.push_back(c->size());
currObj = (c->size() > 0) ? c->front().get() : nullptr;


} else if(currType->classId.id == oatpp::AbstractUnorderedSet::Class::CLASS_ID.id) {

auto c = static_cast<std::unordered_set<oatpp::Void>*>(currObj);
dimensions.push_back(c->size());
currObj = (c->size() > 0) ? c->begin()->get() : nullptr;
auto dispatcher = static_cast<const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(curr.getValueType()->polymorphicDispatcher);
auto size = dispatcher->getCollectionSize(curr);
dimensions.push_back(size);

if(size > 0) {
auto iterator = dispatcher->beginIteration(curr);
curr = iterator->get();
} else {
curr = nullptr;
}

currType = *currType->params.begin();

}

return currType;
return curr.getValueType();

}

Expand All @@ -513,20 +497,84 @@ void Serializer::serializeSubArray(data::stream::ConsistentOutputStream* stream,
{

const oatpp::Type* type = polymorph.getValueType();
if(!type->isCollection) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeSubArray()]: Error. Unknown collection type.");
}

auto dispatcher = static_cast<const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(type->polymorphicDispatcher);
const oatpp::Type* itemType = dispatcher->getItemType();

if(data::mapping::type::__class::AbstractVector::CLASS_ID.id == type->classId.id) {
return serializeSubArray<oatpp::AbstractVector>(stream, polymorph, meta, dimension);
if(dimension < meta.dimensions.size() - 1) {

auto size = meta.dimensions[dimension];

if(dispatcher->getCollectionSize(polymorph) != size) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeSubArray()]. Error. "
"All nested arrays must be of the same size.");
}

auto iterator = dispatcher->beginIteration(polymorph);
while (!iterator->finished()) {
serializeSubArray(stream, iterator->get(), meta, dimension + 1);
iterator->next();
}

} else if(dimension == meta.dimensions.size() - 1) {

auto size = meta.dimensions[dimension];

if(dispatcher->getCollectionSize(polymorph) != size) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeSubArray()]. Error. "
"All nested arrays must be of the same size.");
}

} else if(data::mapping::type::__class::AbstractList::CLASS_ID.id == type->classId.id) {
return serializeSubArray<oatpp::AbstractList>(stream, polymorph, meta, dimension);
auto iterator = dispatcher->beginIteration(polymorph);
while (!iterator->finished()) {

} else if(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id == type->classId.id) {
return serializeSubArray<oatpp::AbstractUnorderedSet>(stream, polymorph, meta, dimension);
OutputData data;
meta._this->serialize(data, iterator->get());

v_int32 itemSize = htonl(data.dataSize);
stream->writeSimple(&itemSize, sizeof(v_int32));

if(data.data != nullptr) {
stream->writeSimple(data.data, data.dataSize);
}

iterator->next();
}

}

}

void Serializer::serializeArray(const Serializer* _this, OutputData& outData, const oatpp::Void& polymorph) {

if(!polymorph) {
serNull(outData);
}

throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeSubArray()]: "
"Error. Unknown 1D collection type.");
ArraySerializationMeta meta;
meta._this = _this;
const oatpp::Type* itemType = getArrayItemTypeAndDimensions(polymorph, meta.dimensions);

if(meta.dimensions.empty()) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeArray()]: Error. "
"Invalid array.");
}

data::stream::BufferOutputStream stream;
ArrayUtils::writeArrayHeader(&stream, _this->getTypeOid(itemType), meta.dimensions);

serializeSubArray(&stream, polymorph, meta, 0);

outData.oid = _this->getArrayTypeOid(itemType);
outData.dataSize = stream.getCurrentPosition();
outData.dataBuffer.reset(new char[outData.dataSize]);
outData.data = outData.dataBuffer.get();
outData.dataFormat = 1;

std::memcpy(outData.data, stream.getData(), outData.dataSize);

}

Expand Down
84 changes: 1 addition & 83 deletions src/oatpp-postgresql/mapping/Serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,89 +125,7 @@ class Serializer {
ArraySerializationMeta& meta,
v_int32 dimension);

template<class Collection>
static void serializeSubArray(data::stream::ConsistentOutputStream* stream,
const oatpp::Void& polymorph,
ArraySerializationMeta& meta,
v_int32 dimension)
{


const oatpp::Type* type = polymorph.getValueType();
const oatpp::Type* itemType = *type->params.begin();

if(dimension < meta.dimensions.size() - 1) {

auto size = meta.dimensions[dimension];
auto arr = polymorph.template cast<Collection>();

if(arr->size() != size) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeSubArray()]. Error. "
"All nested arrays must be of the same size.");
}

for(auto& item : *arr) {
serializeSubArray(stream, item, meta, dimension + 1);
}

} else if(dimension == meta.dimensions.size() - 1) {

auto size = meta.dimensions[dimension];
auto arr = polymorph.template cast<Collection>();

if(arr->size() != size) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeSubArray()]. Error. "
"All nested arrays must be of the same size.");
}

for(auto& item : *arr) {

OutputData data;
meta._this->serialize(data, item);

v_int32 itemSize = htonl(data.dataSize);
stream->writeSimple(&itemSize, sizeof(v_int32));

if(data.data != nullptr) {
stream->writeSimple(data.data, data.dataSize);
}

}

}

}

template<class Collection>
static void serializeArray(const Serializer* _this, OutputData& outData, const oatpp::Void& polymorph) {

if(!polymorph) {
serNull(outData);
}

ArraySerializationMeta meta;
meta._this = _this;
const oatpp::Type* itemType = getArrayItemTypeAndDimensions(polymorph, meta.dimensions);

if(meta.dimensions.empty()) {
throw std::runtime_error("[oatpp::postgresql::mapping::Serializer::serializeArray()]: Error. "
"Invalid array.");
}

data::stream::BufferOutputStream stream;
ArrayUtils::writeArrayHeader(&stream, _this->getTypeOid(itemType), meta.dimensions);

serializeSubArray(&stream, polymorph, meta, 0);

outData.oid = _this->getArrayTypeOid(itemType);
outData.dataSize = stream.getCurrentPosition();
outData.dataBuffer.reset(new char[outData.dataSize]);
outData.data = outData.dataBuffer.get();
outData.dataFormat = 1;

std::memcpy(outData.data, stream.getData(), outData.dataSize);

}
static void serializeArray(const Serializer* _this, OutputData& outData, const oatpp::Void& polymorph);

private:

Expand Down

0 comments on commit 3bc13cb

Please sign in to comment.