Skip to content

Commit 0bc5e16

Browse files
committed
update to the latest oatpp API
1 parent e6293d3 commit 0bc5e16

File tree

5 files changed

+347
-255
lines changed

5 files changed

+347
-255
lines changed

src/oatpp-mongo/bson/mapping/Deserializer.cpp

Lines changed: 195 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ Deserializer::Deserializer(const std::shared_ptr<Config>& config)
5858
//----------------
5959
// Collections
6060

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);
6464

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);
6767

6868

6969
//----------------
@@ -80,11 +80,10 @@ Deserializer::Deserializer(const std::shared_ptr<Config>& config)
8080

8181
void Deserializer::setDeserializerMethod(const data::mapping::type::ClassId& classId, DeserializerMethod method) {
8282
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);
8785
}
86+
m_methods[id] = method;
8887
}
8988

9089
void Deserializer::skipCString(parser::Caret& caret) {
@@ -386,6 +385,167 @@ oatpp::Void Deserializer::deserializeEnum(Deserializer* deserializer,
386385

387386
}
388387

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+
389549
oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
390550
parser::Caret& caret,
391551
const Type* const type,
@@ -414,6 +574,7 @@ oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
414574
auto object = dispatcher->createObject();
415575
const auto& fieldsMap = dispatcher->getProperties()->getMap();
416576

577+
std::vector<PolymorphData> polymorphs;
417578
while(innerCaret.canContinue() && innerCaret.getPosition() < innerCaret.getDataSize() - 1) {
418579

419580
v_char8 valueType;
@@ -428,7 +589,22 @@ oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
428589
if(fieldIterator != fieldsMap.end()){
429590

430591
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+
}
432608

433609
} else if (deserializer->getConfig()->allowUnknownFields) {
434610
skipElement(innerCaret, valueType);
@@ -461,6 +637,15 @@ oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer,
461637
}
462638

463639
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+
464649
return object;
465650

466651
}

0 commit comments

Comments
 (0)