diff --git a/src/oatpp/data/mapping/ObjectToTreeMapper.cpp b/src/oatpp/data/mapping/ObjectToTreeMapper.cpp index 6db12024..6ad03ed4 100644 --- a/src/oatpp/data/mapping/ObjectToTreeMapper.cpp +++ b/src/oatpp/data/mapping/ObjectToTreeMapper.cpp @@ -120,11 +120,6 @@ void ObjectToTreeMapper::mapAny(const ObjectToTreeMapper* mapper, MappingState& void ObjectToTreeMapper::mapEnum(const ObjectToTreeMapper* mapper, MappingState& state, const oatpp::Void& polymorph) { - if(!polymorph) { - state.tree->setNull(); - return; - } - auto polymorphicDispatcher = static_cast( polymorph.getValueType()->polymorphicDispatcher ); diff --git a/src/oatpp/json/ObjectMapper.cpp b/src/oatpp/json/ObjectMapper.cpp index ac36bf20..2c3a6aee 100644 --- a/src/oatpp/json/ObjectMapper.cpp +++ b/src/oatpp/json/ObjectMapper.cpp @@ -26,34 +26,39 @@ namespace oatpp { namespace json { -ObjectMapper::ObjectMapper(const std::shared_ptr& serializerConfig, +ObjectMapper::ObjectMapper(const std::shared_ptr& serializerConfig, const std::shared_ptr& deserializerConfig) : data::mapping::ObjectMapper(getMapperInfo()) - , m_serializer(std::make_shared(serializerConfig)) + , m_serializerConfig(serializerConfig) , m_deserializerConfig(deserializerConfig) {} -ObjectMapper::ObjectMapper(const std::shared_ptr& serializer) - : data::mapping::ObjectMapper(getMapperInfo()) - , m_serializer(serializer) - , m_deserializerConfig(std::make_shared()) -{} - -std::shared_ptr ObjectMapper::createShared(const std::shared_ptr& serializerConfig, +std::shared_ptr ObjectMapper::createShared(const std::shared_ptr& serializerConfig, const std::shared_ptr& deserializerConfig) { return std::make_shared(serializerConfig, deserializerConfig); } -std::shared_ptr ObjectMapper::createShared(const std::shared_ptr& serializer, - const std::shared_ptr& deserializer) -{ - return std::make_shared(serializer); -} +void ObjectMapper::write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant) const { + + data::mapping::Tree tree; + { + data::mapping::ObjectToTreeMapper::MappingState state; + state.config = m_serializerConfig.get(); + state.tree = &tree; + m_objectToTreeMapper.map(state, variant); + if(!state.errorStack.empty()) { + throw std::runtime_error(state.errorStacktrace()); + } + } + + { + Serializer::MappingState state; + state.config = m_serializerConfig.get(); + state.tree = &tree; + Serializer::serializeToStream(stream, state); + } -void ObjectMapper::write(data::stream::ConsistentOutputStream* stream, - const oatpp::Void& variant) const { - m_serializer->serializeToStream(stream, variant); } oatpp::Void ObjectMapper::read(oatpp::utils::parser::Caret& caret, const oatpp::data::mapping::type::Type* const type) const { @@ -90,8 +95,8 @@ oatpp::Void ObjectMapper::read(oatpp::utils::parser::Caret& caret, const oatpp:: } -std::shared_ptr ObjectMapper::getSerializer() { - return m_serializer; +std::shared_ptr ObjectMapper::getSerializerConfig() { + return m_serializerConfig; } std::shared_ptr ObjectMapper::getDeserializerConfig() { diff --git a/src/oatpp/json/ObjectMapper.hpp b/src/oatpp/json/ObjectMapper.hpp index fc142606..242e55f9 100644 --- a/src/oatpp/json/ObjectMapper.hpp +++ b/src/oatpp/json/ObjectMapper.hpp @@ -28,6 +28,7 @@ #include "./Serializer.hpp" #include "./Deserializer.hpp" +#include "oatpp/data/mapping/ObjectToTreeMapper.hpp" #include "oatpp/data/mapping/TreeToObjectMapper.hpp" #include "oatpp/data/mapping/ObjectMapper.hpp" @@ -50,51 +51,31 @@ public: class DeserializerConfig : public data::mapping::TreeToObjectMapper::Config, public Deserializer::Config { public: + }; +public: + + class SerializerConfig : public data::mapping::ObjectToTreeMapper::Config, public Serializer::Config { + public: }; private: - std::shared_ptr m_serializer; + std::shared_ptr m_serializerConfig; std::shared_ptr m_deserializerConfig; private: + data::mapping::ObjectToTreeMapper m_objectToTreeMapper; data::mapping::TreeToObjectMapper m_treeToObjectMapper; public: - /** - * Constructor. - * @param serializerConfig - &id:oatpp::json::Serializer::Config;. - * @param deserializerConfig - &id:oatpp::json::Deserializer::Config;. - */ - ObjectMapper(const std::shared_ptr& serializerConfig, - const std::shared_ptr& deserializerConfig); - /** - * Constructor. - * @param serializer - * @param deserializer - */ - ObjectMapper(const std::shared_ptr& serializer = std::make_shared()); + ObjectMapper(const std::shared_ptr& serializerConfig = std::make_shared(), + const std::shared_ptr& deserializerConfig = std::make_shared()); + public: - /** - * Create shared ObjectMapper. - * @param serializerConfig - &id:oatpp::json::Serializer::Config;. - * @param deserializerConfig - &id:oatpp::json::Deserializer::Config;. - * @return - `std::shared_ptr` to ObjectMapper. - */ static std::shared_ptr - createShared(const std::shared_ptr& serializerConfig, - const std::shared_ptr& deserializerConfig); - - /** - * Create shared ObjectMapper. - * @param serializer - * @param deserializer - * @return - */ - static std::shared_ptr - createShared(const std::shared_ptr& serializer = std::make_shared(), - const std::shared_ptr& deserializer = std::make_shared()); + createShared(const std::shared_ptr& serializerConfig = std::make_shared(), + const std::shared_ptr& deserializerConfig = std::make_shared()); /** * Implementation of &id:oatpp::data::mapping::ObjectMapper::write;. @@ -112,16 +93,8 @@ public: oatpp::Void read(oatpp::utils::parser::Caret& caret, const oatpp::data::mapping::type::Type* const type) const override; - /** - * Get serializer. - * @return - */ - std::shared_ptr getSerializer(); + std::shared_ptr getSerializerConfig(); - /** - * Get deserializer. - * @return - */ std::shared_ptr getDeserializerConfig(); }; diff --git a/src/oatpp/json/Serializer.cpp b/src/oatpp/json/Serializer.cpp index 512e3863..bf925657 100644 --- a/src/oatpp/json/Serializer.cpp +++ b/src/oatpp/json/Serializer.cpp @@ -25,53 +25,17 @@ #include "Serializer.hpp" #include "./Utils.hpp" -#include "oatpp/data/mapping/type/Any.hpp" +#include "oatpp/data/stream/BufferStream.hpp" +#include "oatpp/utils/Conversion.hpp" namespace oatpp { namespace json { -Serializer::Serializer(const std::shared_ptr& config) - : m_config(config) -{ - - m_methods.resize(static_cast(data::mapping::type::ClassId::getClassCount()), nullptr); - - setSerializerMethod(data::mapping::type::__class::String::CLASS_ID, &Serializer::serializeString); - setSerializerMethod(data::mapping::type::__class::Any::CLASS_ID, &Serializer::serializeAny); - - setSerializerMethod(data::mapping::type::__class::Int8::CLASS_ID, &Serializer::serializePrimitive); - setSerializerMethod(data::mapping::type::__class::UInt8::CLASS_ID, &Serializer::serializePrimitive); - - setSerializerMethod(data::mapping::type::__class::Int16::CLASS_ID, &Serializer::serializePrimitive); - setSerializerMethod(data::mapping::type::__class::UInt16::CLASS_ID, &Serializer::serializePrimitive); - - setSerializerMethod(data::mapping::type::__class::Int32::CLASS_ID, &Serializer::serializePrimitive); - setSerializerMethod(data::mapping::type::__class::UInt32::CLASS_ID, &Serializer::serializePrimitive); - - setSerializerMethod(data::mapping::type::__class::Int64::CLASS_ID, &Serializer::serializePrimitive); - setSerializerMethod(data::mapping::type::__class::UInt64::CLASS_ID, &Serializer::serializePrimitive); - - setSerializerMethod(data::mapping::type::__class::Float32::CLASS_ID, &Serializer::serializePrimitive); - setSerializerMethod(data::mapping::type::__class::Float64::CLASS_ID, &Serializer::serializePrimitive); - setSerializerMethod(data::mapping::type::__class::Boolean::CLASS_ID, &Serializer::serializePrimitive); - - setSerializerMethod(data::mapping::type::__class::AbstractObject::CLASS_ID, &Serializer::serializeObject); - setSerializerMethod(data::mapping::type::__class::AbstractEnum::CLASS_ID, &Serializer::serializeEnum); - - setSerializerMethod(data::mapping::type::__class::AbstractVector::CLASS_ID, &Serializer::serializeCollection); - setSerializerMethod(data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeCollection); - setSerializerMethod(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Serializer::serializeCollection); - - setSerializerMethod(data::mapping::type::__class::AbstractPairList::CLASS_ID, &Serializer::serializeMap); - setSerializerMethod(data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Serializer::serializeMap); - -} - -void Serializer::setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method) { - const v_uint32 id = static_cast(classId.id); - if(id >= m_methods.size()) { - m_methods.resize(id + 1, nullptr); +oatpp::String Serializer::MappingState::errorStacktrace() const { + data::stream::BufferOutputStream ss; + for(auto& s : errorStack) { + ss << s << "\n"; } - m_methods[id] = method; + return ss.toString(); } void Serializer::serializeString(data::stream::ConsistentOutputStream* stream, const char* data, v_buff_size size, v_uint32 escapeFlags) { @@ -81,222 +45,188 @@ void Serializer::serializeString(data::stream::ConsistentOutputStream* stream, c stream->writeCharSimple('\"'); } -void Serializer::serializeString(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ +void Serializer::serializeNull(MappingState& state) { + state.stream->writeSimple("null"); +} + +void Serializer::serializeString(MappingState& state) { + const auto& str = state.tree->getString(); + serializeString(state.stream, str->data(), static_cast(str->size()), state.config->escapeFlags); +} + +void Serializer::serializeArray(MappingState& state) { + + state.stream->writeCharSimple('['); + + MappingState nestedState; + nestedState.stream = state.stream; + nestedState.config = state.config; + + auto& vector = state.tree->getVector(); + + v_int64 index = 0; + for(auto& tree : vector) { + + nestedState.tree = &tree; + + if(!tree.isNull() || state.config->includeNullElements) { + + if(index > 0) state.stream->writeSimple(",", 1); + + serialize(nestedState); + + if(!nestedState.errorStack.empty()) { + state.errorStack.splice(state.errorStack.end(), nestedState.errorStack); + state.errorStack.emplace_back("[oatpp::json::Serializer::serializeArray()]: index=" + utils::Conversion::int64ToStr(index)); + return; + } + } + + index ++; - if(!polymorph) { - stream->writeSimple("null", 4); - return; } - auto str = static_cast(polymorph.get()); - - serializeString(stream, str->data(), static_cast(str->size()), serializer->m_config->escapeFlags); + state.stream->writeCharSimple(']'); } -void Serializer::serializeAny(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ +void Serializer::serializeMap(MappingState& state) { + + state.stream->writeCharSimple('{'); + + MappingState nestedState; + nestedState.stream = state.stream; + nestedState.config = state.config; + + auto& map = state.tree->getMap(); + auto mapSize = map.size(); + + for(v_uint64 index = 0; index < mapSize; index ++) { + + const auto& pair = map[index]; + + nestedState.tree = &pair.second.get(); + + if(!nestedState.tree->isNull() || state.config->includeNullElements) { + + if(index > 0) state.stream->writeSimple(",", 1); + + const auto& str = pair.first; + serializeString(state.stream, str->data(), static_cast(str->size()), state.config->escapeFlags); + state.stream->writeCharSimple(':'); + + serialize(nestedState); + + if(!nestedState.errorStack.empty()) { + state.errorStack.splice(state.errorStack.end(), nestedState.errorStack); + state.errorStack.emplace_back("[oatpp::json::Serializer::serializeMap()]: key='" + pair.first + "'"); + return; + } + } - if(!polymorph) { - stream->writeSimple("null", 4); - return; } - auto anyHandle = static_cast(polymorph.get()); - serializer->serialize(stream, oatpp::Void(anyHandle->ptr, anyHandle->type)); + state.stream->writeCharSimple('}'); } -void Serializer::serializeEnum(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ - auto polymorphicDispatcher = static_cast( - polymorph.getValueType()->polymorphicDispatcher - ); +void Serializer::serializePairs(MappingState& state) { - data::mapping::type::EnumInterpreterError e = data::mapping::type::EnumInterpreterError::OK; - serializer->serialize(stream, polymorphicDispatcher->toInterpretation(polymorph, e)); + state.stream->writeCharSimple('{'); + + MappingState nestedState; + nestedState.stream = state.stream; + nestedState.config = state.config; + + auto& map = state.tree->getPairs(); + auto mapSize = map.size(); + + for(v_uint64 index = 0; index < mapSize; index ++) { + + const auto& pair = map[index]; + + nestedState.tree = &pair.second; + + if(!nestedState.tree->isNull() || state.config->includeNullElements) { + + if(index > 0) state.stream->writeSimple(",", 1); + + const auto& str = pair.first; + serializeString(state.stream, str->data(), static_cast(str->size()), state.config->escapeFlags); + state.stream->writeCharSimple(':'); + + serialize(nestedState); + + if(!nestedState.errorStack.empty()) { + state.errorStack.splice(state.errorStack.end(), nestedState.errorStack); + state.errorStack.emplace_back("[oatpp::json::Serializer::serializeMap()]: key='" + pair.first + "'"); + return; + } + } - if(e == data::mapping::type::EnumInterpreterError::OK) { - return; } - switch(e) { - case data::mapping::type::EnumInterpreterError::CONSTRAINT_NOT_NULL: - throw std::runtime_error("[oatpp::json::Serializer::serializeEnum()]: Error. Enum constraint violated - 'NotNull'."); - case data::mapping::type::EnumInterpreterError::OK: - case data::mapping::type::EnumInterpreterError::TYPE_MISMATCH_ENUM: - case data::mapping::type::EnumInterpreterError::TYPE_MISMATCH_ENUM_VALUE: - case data::mapping::type::EnumInterpreterError::ENTRY_NOT_FOUND: + state.stream->writeCharSimple('}'); + +} + +void Serializer::serialize(MappingState& state) { + + switch (state.tree->getType()) { + + case data::mapping::Tree::Type::UNDEFINED: break; + case data::mapping::Tree::Type::NULL_VALUE: serializeNull(state); return; + + case data::mapping::Tree::Type::INTEGER: state.stream->writeAsString(state.tree->getInteger()); return; + case data::mapping::Tree::Type::FLOAT: state.stream->writeAsString(state.tree->getFloat()); return; + + case data::mapping::Tree::Type::BOOL: state.stream->writeAsString(state.tree->getValue()); return; + + case data::mapping::Tree::Type::INT_8: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::UINT_8: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::INT_16: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::UINT_16: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::INT_32: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::UINT_32: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::INT_64: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::UINT_64: state.stream->writeAsString(state.tree->getValue()); return; + + case data::mapping::Tree::Type::FLOAT_32: state.stream->writeAsString(state.tree->getValue()); return; + case data::mapping::Tree::Type::FLOAT_64: state.stream->writeAsString(state.tree->getValue()); return; + + case data::mapping::Tree::Type::STRING: serializeString(state); return; + case data::mapping::Tree::Type::VECTOR: serializeArray(state); return; + case data::mapping::Tree::Type::MAP: serializeMap(state); return; + case data::mapping::Tree::Type::PAIRS: serializePairs(state); return; + default: - throw std::runtime_error("[oatpp::json::Serializer::serializeEnum()]: Error. Can't serialize Enum."); + break; + } + state.errorStack.emplace_back("[oatpp::json::Serializer::serialize()]: Unknown node type"); + } -void Serializer::serializeCollection(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ +void Serializer::serializeToStream(data::stream::ConsistentOutputStream* stream, MappingState& state) { - if(!polymorph) { - stream->writeSimple("null", 4); - return; - } + if(state.config->useBeautifier) { - auto dispatcher = static_cast( - polymorph.getValueType()->polymorphicDispatcher - ); - - stream->writeCharSimple('['); - bool first = true; - - auto iterator = dispatcher->beginIteration(polymorph); - - while (!iterator->finished()) { - const auto& value = iterator->get(); - if(value || serializer->getConfig()->includeNullFields || serializer->getConfig()->alwaysIncludeNullCollectionElements) { - (first) ? first = false : stream->writeSimple(",", 1); - serializer->serialize(stream, value); - } - iterator->next(); - } - - stream->writeCharSimple(']'); - -} - -void Serializer::serializeMap(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ - - if(!polymorph) { - stream->writeSimple("null", 4); - return; - } - - auto dispatcher = static_cast( - polymorph.getValueType()->polymorphicDispatcher - ); - - auto keyType = dispatcher->getKeyType(); - if(keyType->classId != oatpp::String::Class::CLASS_ID){ - throw std::runtime_error("[oatpp::json::Serializer::serializeMap()]: Invalid json map key. Key should be String"); - } - - stream->writeCharSimple('{'); - bool first = true; - - auto iterator = dispatcher->beginIteration(polymorph); - - while (!iterator->finished()) { - const auto& value = iterator->getValue(); - if(value || serializer->m_config->includeNullFields || serializer->m_config->alwaysIncludeNullCollectionElements) { - (first) ? first = false : stream->writeSimple(",", 1); - const auto& untypedKey = iterator->getKey(); - const auto& key = oatpp::String(std::static_pointer_cast(untypedKey.getPtr())); - serializeString(stream, key->data(), static_cast(key->size()), serializer->m_config->escapeFlags); - stream->writeSimple(":", 1); - serializer->serialize(stream, value); - } - iterator->next(); - } - - stream->writeCharSimple('}'); - -} - -void Serializer::serializeObject(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ - - if(!polymorph) { - stream->writeSimple("null", 4); - return; - } - - stream->writeCharSimple('{'); - - bool first = true; - auto type = polymorph.getValueType(); - auto dispatcher = static_cast( - type->polymorphicDispatcher - ); - auto fields = dispatcher->getProperties()->getList(); - auto object = static_cast(polymorph.get()); - auto config = serializer->m_config; - - for (auto const& field : fields) { - - oatpp::Void value; - if(field->info.typeSelector && field->type == oatpp::Any::Class::getType()) { - const auto& any = field->get(object).cast(); - value = any.retrieve(field->info.typeSelector->selectType(object)); - } else { - value = field->get(object); - } - - if(field->info.required && value == nullptr) { - throw std::runtime_error("[oatpp::json::Serializer::serialize()]: " - "Error. " + std::string(type->nameQualifier) + "::" - + std::string(field->name) + " is required!"); - } - - if (value || config->includeNullFields || (field->info.required && config->alwaysIncludeRequired)) { - (first) ? first = false : stream->writeSimple(",", 1); - serializeString(stream, field->name, static_cast(std::strlen(field->name)), serializer->m_config->escapeFlags); - stream->writeSimple(":", 1); - serializer->serialize(stream, value); - } - - } - - stream->writeCharSimple('}'); - -} - -void Serializer::serialize(data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ - auto id = static_cast(polymorph.getValueType()->classId.id); - auto& method = m_methods[id]; - if(method) { - (*method)(this, stream, polymorph); - } else { - - auto* interpretation = polymorph.getValueType()->findInterpretation(m_config->enabledInterpretations); - if(interpretation) { - serialize(stream, interpretation->toInterpretation(polymorph)); - } else { - throw std::runtime_error("[oatpp::json::Serializer::serialize()]: " - "Error. No serialize method for type '" + - std::string(polymorph.getValueType()->classId.name) + "'"); - } - - } -} - -void Serializer::serializeToStream(data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph) -{ - if(m_config->useBeautifier) { json::Beautifier beautifier(stream, " ", "\n"); - serialize(&beautifier, polymorph); - } else { - serialize(stream, polymorph); - } -} -const std::shared_ptr& Serializer::getConfig() { - return m_config; + MappingState beautifulState; + beautifulState.stream = &beautifier; + beautifulState.tree = state.tree; + beautifulState.config = state.config; + serialize(beautifulState); + + state.errorStack = std::move(beautifulState.errorStack); + + } else { + state.stream = stream; + serialize(state); + } + } }} diff --git a/src/oatpp/json/Serializer.hpp b/src/oatpp/json/Serializer.hpp index 453f461f..d2fde80a 100644 --- a/src/oatpp/json/Serializer.hpp +++ b/src/oatpp/json/Serializer.hpp @@ -27,8 +27,8 @@ #include "./Utils.hpp" #include "./Beautifier.hpp" +#include "oatpp/data/mapping/Tree.hpp" #include "oatpp/Types.hpp" -#include namespace oatpp { namespace json { @@ -38,55 +38,18 @@ namespace oatpp { namespace json { */ class Serializer { public: - typedef oatpp::data::mapping::type::Type Type; - typedef oatpp::data::mapping::type::BaseObject::Property Property; - typedef oatpp::data::mapping::type::BaseObject::Properties Properties; - typedef oatpp::String String; -public: /** * Serializer config. */ class Config : public oatpp::base::Countable { public: - /** - * Constructor. - */ - Config() - {} - public: - - /** - * Create shared config. - * @return - `std::shared_ptr` to Config. - */ - static std::shared_ptr createShared(){ - return std::make_shared(); - } /** * Include fields with value == nullptr into serialized json. * Field will still be included when field-info `required` is set to true and &id:alwaysIncludeRequired is set to true. */ - bool includeNullFields = true; - - /** - * Always include required fields (set in in DTO_FIELD_INFO) even if they are `value == nullptr` - */ - bool alwaysIncludeRequired = false; - - /** - * Always include array or map elements, even if their value is `nullptr`. - */ - bool alwaysIncludeNullCollectionElements = false; - - /** - * If `true` - insert string `""` in json field value in case unknown field found. - * Fail if `false`. - * Known types for this serializer are:
- * (String, Int8, Int16, Int32, Int64, Float32, Float64, Boolean, DTOs, List, Fields). - */ - bool throwOnUnknownTypes = true; + bool includeNullElements = true; /** * Use JSON Beautifier. @@ -103,97 +66,45 @@ public: */ oatpp::String beautifierNewLine = "\n"; - /** - * Enable type interpretations. - */ - std::vector enabledInterpretations = {}; - /** * Escape flags. */ v_uint32 escapeFlags = json::Utils::FLAG_ESCAPE_ALL; }; + public: - typedef void (*SerializerMethod)(Serializer*, - data::stream::ConsistentOutputStream*, - const oatpp::Void&); + + struct MappingState { + + Config* config; + const data::mapping::Tree* tree; + data::stream::ConsistentOutputStream* stream; + + std::list errorStack; + oatpp::String errorStacktrace() const; + + }; + private: - template - static void serializePrimitive(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph){ - (void) serializer; - - if(polymorph){ - stream->writeAsString(* static_cast(polymorph.get())); - } else { - stream->writeSimple("null", 4); - } - } static void serializeString(oatpp::data::stream::ConsistentOutputStream* stream, const char* data, v_buff_size size, v_uint32 escapeFlags); - static void serializeString(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph); + static void serializeNull(MappingState& state); + static void serializeString(MappingState& state); + static void serializeArray(MappingState& state); + static void serializeMap(MappingState& state); + static void serializePairs(MappingState& state); - static void serializeAny(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph); + static void serialize(MappingState& state); - static void serializeEnum(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph); - - static void serializeCollection(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph); - - static void serializeMap(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph); - - static void serializeObject(Serializer* serializer, - data::stream::ConsistentOutputStream* stream, - const oatpp::Void& polymorph); - - void serialize(data::stream::ConsistentOutputStream* stream, const oatpp::Void& polymorph); - -private: - std::shared_ptr m_config; - std::vector m_methods; public: - /** - * Constructor. - * @param config - serializer config. - */ - Serializer(const std::shared_ptr& config = std::make_shared()); - - /** - * Set serializer method for type. - * @param classId - &id:oatpp::data::mapping::type::ClassId;. - * @param method - `typedef void (*SerializerMethod)(Serializer*, data::stream::ConsistentOutputStream*, const oatpp::Void&)`. - */ - void setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method); - - /** - * Serialize object to stream. - * @param stream - &id:oatpp::data::stream::ConsistentOutputStream;. - * @param polymorph - DTO as &id:oatpp::Void;. - */ - void serializeToStream(data::stream::ConsistentOutputStream* stream, const oatpp::Void& polymorph); - - /** - * Get serializer config. - * @return - */ - const std::shared_ptr& getConfig(); + static void serializeToStream(data::stream::ConsistentOutputStream* stream, MappingState& state); }; diff --git a/test/oatpp/data/mapping/TreeToObjectMapperTest.cpp b/test/oatpp/data/mapping/TreeToObjectMapperTest.cpp index 345b880e..22ddf4bd 100644 --- a/test/oatpp/data/mapping/TreeToObjectMapperTest.cpp +++ b/test/oatpp/data/mapping/TreeToObjectMapperTest.cpp @@ -69,8 +69,8 @@ class TestDto1 : public oatpp::DTO { void TreeToObjectMapperTest::onRun() { json::ObjectMapper jsonMapper; - jsonMapper.getSerializer()->getConfig()->useBeautifier = true; - jsonMapper.getSerializer()->getConfig()->includeNullFields = false; + jsonMapper.getSerializerConfig()->useBeautifier = true; + jsonMapper.getSerializerConfig()->includeNullFields = false; TreeToObjectMapper mapper; TreeToObjectMapper::Config config; diff --git a/test/oatpp/data/mapping/type/InterpretationTest.cpp b/test/oatpp/data/mapping/type/InterpretationTest.cpp index 8e2505c0..ed5c04e9 100644 --- a/test/oatpp/data/mapping/type/InterpretationTest.cpp +++ b/test/oatpp/data/mapping/type/InterpretationTest.cpp @@ -176,7 +176,7 @@ void InterpretationTest::onRun() { oatpp::json::ObjectMapper mapper; { - auto config = mapper.getSerializer()->getConfig(); + auto config = mapper.getSerializerConfig(); config->enabledInterpretations = {"test"}; config->useBeautifier = false; } diff --git a/test/oatpp/json/DTOMapperTest.cpp b/test/oatpp/json/DTOMapperTest.cpp index 1d802f3a..71118773 100644 --- a/test/oatpp/json/DTOMapperTest.cpp +++ b/test/oatpp/json/DTOMapperTest.cpp @@ -165,7 +165,7 @@ class TestAnyNested : public oatpp::DTO { void DTOMapperTest::onRun(){ auto mapper = oatpp::json::ObjectMapper::createShared(); - mapper->getSerializer()->getConfig()->useBeautifier = true; + mapper->getSerializerConfig()->useBeautifier = true; { auto test1 = Test::createShared();