json::mapping::ObjectMapper. Remove old Serializer.

This commit is contained in:
lganzzzo 2020-01-22 11:11:21 +07:00
parent 3c5c0d8f67
commit fc26498f45
9 changed files with 195 additions and 529 deletions

View File

@ -232,7 +232,7 @@ add_library(oatpp
oatpp/web/url/mapping/Pattern.cpp
oatpp/web/url/mapping/Pattern.hpp
oatpp/web/url/mapping/Router.hpp
oatpp/parser/json/mapping/Serializer2.cpp oatpp/parser/json/mapping/Serializer2.hpp)
)
set_target_properties(oatpp PROPERTIES
CXX_STANDARD 11

View File

@ -26,15 +26,15 @@
namespace oatpp { namespace parser { namespace json { namespace mapping {
ObjectMapper::ObjectMapper(const std::shared_ptr<Serializer2::Config>& pSerializerConfig,
ObjectMapper::ObjectMapper(const std::shared_ptr<Serializer::Config>& pSerializerConfig,
const std::shared_ptr<Deserializer::Config>& pDeserializerConfig)
: data::mapping::ObjectMapper(getMapperInfo())
, m_serializer(std::make_shared<Serializer2>(pSerializerConfig))
, m_serializer(std::make_shared<Serializer>(pSerializerConfig))
, serializerConfig(pSerializerConfig)
, deserializerConfig(pDeserializerConfig)
{}
std::shared_ptr<ObjectMapper> ObjectMapper::createShared(const std::shared_ptr<Serializer2::Config>& serializerConfig,
std::shared_ptr<ObjectMapper> ObjectMapper::createShared(const std::shared_ptr<Serializer::Config>& serializerConfig,
const std::shared_ptr<Deserializer::Config>& deserializerConfig){
return std::make_shared<ObjectMapper>(serializerConfig, deserializerConfig);
}

View File

@ -25,7 +25,7 @@
#ifndef oatpp_parser_json_mapping_ObjectMapper_hpp
#define oatpp_parser_json_mapping_ObjectMapper_hpp
#include "./Serializer2.hpp"
#include "./Serializer.hpp"
#include "./Deserializer.hpp"
#include "oatpp/core/data/mapping/ObjectMapper.hpp"
@ -44,14 +44,14 @@ private:
return info;
}
private:
std::shared_ptr<Serializer2> m_serializer;
std::shared_ptr<Serializer> m_serializer;
public:
/**
* Constructor.
* @param pSerializerConfig - &id:oatpp::parser::json::mapping::Serializer::Config;.
* @param pDeserializerConfig - &id:oatpp::parser::json::mapping::Deserializer::Config;.
*/
ObjectMapper(const std::shared_ptr<Serializer2::Config>& pSerializerConfig = Serializer2::Config::createShared(),
ObjectMapper(const std::shared_ptr<Serializer::Config>& pSerializerConfig = Serializer::Config::createShared(),
const std::shared_ptr<Deserializer::Config>& pDeserializerConfig = Deserializer::Config::createShared());
public:
@ -62,7 +62,7 @@ public:
* @return - `std::shared_ptr` to ObjectMapper.
*/
static std::shared_ptr<ObjectMapper>
createShared(const std::shared_ptr<Serializer2::Config>& serializerConfig = Serializer2::Config::createShared(),
createShared(const std::shared_ptr<Serializer::Config>& serializerConfig = Serializer::Config::createShared(),
const std::shared_ptr<Deserializer::Config>& deserializerConfig = Deserializer::Config::createShared());
/**
@ -85,7 +85,7 @@ public:
/**
* Serializer config.
*/
std::shared_ptr<Serializer2::Config> serializerConfig;
std::shared_ptr<Serializer::Config> serializerConfig;
/**
* Deserializer config.

View File

@ -27,153 +27,168 @@
#include "oatpp/parser/json/Utils.hpp"
namespace oatpp { namespace parser { namespace json { namespace mapping {
void Serializer::writeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size) {
Serializer::Serializer(const std::shared_ptr<Config>& config)
: m_config(config)
{
m_methods.resize(data::mapping::type::ClassId::getClassCount(), nullptr);
m_methods[oatpp::data::mapping::type::__class::String::CLASS_ID.id] = &Serializer::serializeString;
m_methods[oatpp::data::mapping::type::__class::Int8::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Int8>;
m_methods[oatpp::data::mapping::type::__class::Int16::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Int16>;
m_methods[oatpp::data::mapping::type::__class::Int32::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Int32>;
m_methods[oatpp::data::mapping::type::__class::Int64::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Int64>;
m_methods[oatpp::data::mapping::type::__class::Float32::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Float32>;
m_methods[oatpp::data::mapping::type::__class::Float64::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Float64>;
m_methods[oatpp::data::mapping::type::__class::Boolean::CLASS_ID.id] = &Serializer::serializePrimitive<oatpp::Boolean>;
m_methods[oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id] = &Serializer::serializeObject;
m_methods[oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id] = &Serializer::serializeList;
m_methods[oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID.id] = &Serializer::serializeFieldsMap;
}
void Serializer::setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method) {
auto id = classId.id;
if(id < m_methods.size()) {
m_methods[id] = method;
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::setSerializerMethod()]: Error. Unknown classId");
}
}
void Serializer::serializeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size) {
auto encodedValue = Utils::escapeString(data, size, false);
stream->writeCharSimple('\"');
stream->writeSimple(encodedValue);
stream->writeCharSimple('\"');
}
void Serializer::writeString(oatpp::data::stream::ConsistentOutputStream* stream, const char* data) {
writeString(stream, (p_char8)data, std::strlen(data));
}
void Serializer::writeList(oatpp::data::stream::ConsistentOutputStream* stream, const AbstractList::ObjectWrapper& list, const std::shared_ptr<Config>& config) {
stream->writeCharSimple('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = curr->getData();
if(value || config->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
writeValue(stream, curr->getData(), config);
}
curr = curr->getNext();
}
stream->writeCharSimple(']');
}
void Serializer::writeFieldsMap(oatpp::data::stream::ConsistentOutputStream* stream, const AbstractFieldsMap::ObjectWrapper& map, const std::shared_ptr<Config>& config) {
stream->writeCharSimple('{');
bool first = true;
auto curr = map->getFirstEntry();
while(curr != nullptr){
auto value = curr->getValue();
if(value || config->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
auto key = curr->getKey();
writeString(stream, key->getData(), key->getSize());
stream->writeSimple(":", 1);
writeValue(stream, curr->getValue(), config);
}
curr = curr->getNext();
}
stream->writeCharSimple('}');
}
void Serializer::writeObject(oatpp::data::stream::ConsistentOutputStream* stream, const PolymorphicWrapper<Object>& polymorph, const std::shared_ptr<Config>& config) {
stream->writeCharSimple('{');
bool first = true;
auto fields = polymorph.valueType->properties->getList();
Object* object = polymorph.get();
for (auto const& field : fields) {
auto value = field->get(object);
if(value || config->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
writeString(stream, field->name);
stream->writeSimple(":", 1);
writeValue(stream, value, config);
}
}
stream->writeCharSimple('}');
}
void Serializer::writeValue(oatpp::data::stream::ConsistentOutputStream* stream, const AbstractObjectWrapper& polymorph, const std::shared_ptr<Config>& config) {
void Serializer::serializeString(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto classId = polymorph.valueType->classId.id;
if(classId == oatpp::data::mapping::type::__class::String::CLASS_ID.id) {
auto str = oatpp::data::mapping::type::static_wrapper_cast<oatpp::base::StrBuffer>(polymorph);
writeString(stream, str->getData(), str->getSize());
} else if(classId == oatpp::data::mapping::type::__class::Int8::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Int8::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::Int16::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Int16::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::Int32::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Int32::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::Int64::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Int64::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::Float32::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Float32::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::Float64::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Float64::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::Boolean::CLASS_ID.id) {
writeSimpleData(stream, oatpp::data::mapping::type::static_wrapper_cast<Boolean::ObjectType>(polymorph));
} else if(classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id) {
writeList(stream, oatpp::data::mapping::type::static_wrapper_cast<AbstractList>(polymorph), config);
} else if(classId == oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID.id) {
// TODO Assert that key is String
writeFieldsMap(stream, oatpp::data::mapping::type::static_wrapper_cast<AbstractFieldsMap>(polymorph), config);
} else if(classId == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id) {
writeObject(stream, oatpp::data::mapping::type::static_wrapper_cast<Object>(polymorph), config);
} else {
if(config->throwOnUnknownTypes) {
throw std::runtime_error("[oatpp::kafka::protocol::mapping::Serializer::writeField]: Unknown data type");
} else {
writeString(stream, "<unknown-type>");
auto str = static_cast<oatpp::base::StrBuffer*>(polymorph.get());
serializeString(stream, str->getData(), str->getSize());
}
void Serializer::serializeList(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto* list = static_cast<AbstractList*>(polymorph.get());
stream->writeCharSimple('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = curr->getData();
if(value || serializer->getConfig()->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
serializer->serialize(stream, curr->getData());
}
curr = curr->getNext();
}
stream->writeCharSimple(']');
}
void Serializer::serializeToStream(oatpp::data::stream::ConsistentOutputStream* stream,
const oatpp::data::mapping::type::AbstractObjectWrapper& polymorph,
const std::shared_ptr<Config>& config)
void Serializer::serializeFieldsMap(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
auto type = polymorph.valueType;
if(type->classId.id == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id) {
writeObject(stream, oatpp::data::mapping::type::static_wrapper_cast<Object>(polymorph), config);
} else if(type->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id) {
writeList(stream, oatpp::data::mapping::type::static_wrapper_cast<AbstractList>(polymorph), config);
} else if(type->classId.id == oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID.id) {
writeFieldsMap(stream, oatpp::data::mapping::type::static_wrapper_cast<AbstractFieldsMap>(polymorph), config);
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serialize()]: Unknown parameter type");
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto map = static_cast<AbstractFieldsMap*>(polymorph.get());
stream->writeCharSimple('{');
bool first = true;
auto curr = map->getFirstEntry();
while(curr != nullptr){
auto value = curr->getValue();
if(value || serializer->getConfig()->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
auto key = curr->getKey();
serializeString(stream, key->getData(), key->getSize());
stream->writeSimple(":", 1);
serializer->serialize(stream, curr->getValue());
}
curr = curr->getNext();
}
stream->writeCharSimple('}');
}
void Serializer::serialize(const std::shared_ptr<oatpp::data::stream::ConsistentOutputStream>& stream,
const oatpp::data::mapping::type::AbstractObjectWrapper& polymorph,
const std::shared_ptr<Config>& config)
void Serializer::serializeObject(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(config->useBeautifier) {
json::Beautifier beautifier(stream.get(), " ", "\n");
serializeToStream(&beautifier, polymorph, config);
} else {
serializeToStream(stream.get(), polymorph, config);
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
stream->writeCharSimple('{');
bool first = true;
auto fields = polymorph.valueType->properties->getList();
Object* object = static_cast<Object*>(polymorph.get());
for (auto const& field : fields) {
auto value = field->get(object);
if(value || serializer->getConfig()->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
serializeString(stream, (p_char8)field->name, std::strlen(field->name));
stream->writeSimple(":", 1);
serializer->serialize(stream, value);
}
}
stream->writeCharSimple('}');
}
void Serializer::serialize(data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
auto id = polymorph.valueType->classId.id;
auto& method = m_methods[id];
if(method) {
(*method)(this, stream, polymorph);
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serialize()]: "
"Error. No serialize method for type '" + std::string(polymorph.valueType->classId.name) + "'");
}
}
const std::shared_ptr<Serializer::Config>& Serializer::getConfig() {
return m_config;
}
}}}}

View File

@ -39,6 +39,8 @@
#include "oatpp/core/collection/LinkedList.hpp"
#include "oatpp/core/Types.hpp"
#include <vector>
namespace oatpp { namespace parser { namespace json { namespace mapping {
/**
@ -50,17 +52,17 @@ public:
typedef oatpp::data::mapping::type::Type Type;
typedef oatpp::data::mapping::type::Type::Property Property;
typedef oatpp::data::mapping::type::Type::Properties Properties;
typedef oatpp::data::mapping::type::Object Object;
typedef oatpp::String String;
template<class T>
using PolymorphicWrapper = data::mapping::type::PolymorphicWrapper<T>;
typedef oatpp::data::mapping::type::AbstractObjectWrapper AbstractObjectWrapper;
typedef oatpp::data::mapping::type::List<AbstractObjectWrapper> AbstractList;
typedef oatpp::data::mapping::type::ListMap<String, AbstractObjectWrapper> AbstractFieldsMap;
public:
/**
* Serializer config.
@ -109,47 +111,56 @@ public:
* Beautifier new line.
*/
oatpp::String beautifierNewLine = "\n";
};
public:
typedef void (*SerializerMethod)(Serializer*,
data::stream::ConsistentOutputStream*,
const data::mapping::type::AbstractObjectWrapper&);
private:
static void writeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size);
static void writeString(oatpp::data::stream::ConsistentOutputStream* stream, const char* data);
template<class T>
static void writeSimpleData(oatpp::data::stream::ConsistentOutputStream* stream, const PolymorphicWrapper<T>& value){
if(value){
stream->writeAsString(value.get()->getValue());
static void serializePrimitive(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph){
if(polymorph){
stream->writeAsString(static_cast<typename T::ObjectType*>(polymorph.get())->getValue());
} else {
stream->writeSimple("null", 4);
}
}
static void writeList(oatpp::data::stream::ConsistentOutputStream* stream, const AbstractList::ObjectWrapper& list, const std::shared_ptr<Config>& config);
static void writeFieldsMap(oatpp::data::stream::ConsistentOutputStream* stream, const AbstractFieldsMap::ObjectWrapper& map, const std::shared_ptr<Config>& config);
static void writeObject(oatpp::data::stream::ConsistentOutputStream* stream, const PolymorphicWrapper<Object>& polymorph, const std::shared_ptr<Config>& config);
static void writeValue(oatpp::data::stream::ConsistentOutputStream* stream, const AbstractObjectWrapper& polymorph, const std::shared_ptr<Config>& config);
static void serializeToStream(oatpp::data::stream::ConsistentOutputStream* stream,
const oatpp::data::mapping::type::AbstractObjectWrapper& polymorph,
const std::shared_ptr<Config>& config);
static void serializeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size);
static void serializeString(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
static void serializeList(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
static void serializeFieldsMap(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
static void serializeObject(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
private:
std::vector<SerializerMethod> m_methods;
std::shared_ptr<Config> m_config;
public:
/**
* Serialize DTO object to stream.
* @param stream - stream to write serialized object to. &id:oatpp::data::stream::ConsistentOutputStream;. <br>
* @param polymorph - DTO object to serialize.
* @param config - &l:Serializer::Config;.
*/
static void serialize(const std::shared_ptr<oatpp::data::stream::ConsistentOutputStream>& stream,
const oatpp::data::mapping::type::AbstractObjectWrapper& polymorph,
const std::shared_ptr<Config>& config);
Serializer(const std::shared_ptr<Config>& config = std::make_shared<Config>());
void setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method);
void serialize(data::stream::ConsistentOutputStream* stream, const data::mapping::type::AbstractObjectWrapper& polymorph);
const std::shared_ptr<Config>& getConfig();
};
}}}}
#endif /* oatpp_parser_json_mapping_Serializer_hpp */

View File

@ -1,194 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#include "Serializer2.hpp"
#include "oatpp/parser/json/Utils.hpp"
namespace oatpp { namespace parser { namespace json { namespace mapping {
Serializer2::Serializer2(const std::shared_ptr<Config>& config)
: m_config(config)
{
m_methods.resize(data::mapping::type::ClassId::getClassCount(), nullptr);
m_methods[oatpp::data::mapping::type::__class::String::CLASS_ID.id] = &Serializer2::serializeString;
m_methods[oatpp::data::mapping::type::__class::Int8::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Int8>;
m_methods[oatpp::data::mapping::type::__class::Int16::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Int16>;
m_methods[oatpp::data::mapping::type::__class::Int32::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Int32>;
m_methods[oatpp::data::mapping::type::__class::Int64::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Int64>;
m_methods[oatpp::data::mapping::type::__class::Float32::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Float32>;
m_methods[oatpp::data::mapping::type::__class::Float64::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Float64>;
m_methods[oatpp::data::mapping::type::__class::Boolean::CLASS_ID.id] = &Serializer2::serializePrimitive<oatpp::Boolean>;
m_methods[oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id] = &Serializer2::serializeObject;
m_methods[oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id] = &Serializer2::serializeList;
m_methods[oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID.id] = &Serializer2::serializeFieldsMap;
}
void Serializer2::setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method) {
auto id = classId.id;
if(id < m_methods.size()) {
m_methods[id] = method;
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::setSerializerMethod()]: Error. Unknown classId");
}
}
void Serializer2::serializeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size) {
auto encodedValue = Utils::escapeString(data, size, false);
stream->writeCharSimple('\"');
stream->writeSimple(encodedValue);
stream->writeCharSimple('\"');
}
void Serializer2::serializeString(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto str = static_cast<oatpp::base::StrBuffer*>(polymorph.get());
serializeString(stream, str->getData(), str->getSize());
}
void Serializer2::serializeList(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto* list = static_cast<AbstractList*>(polymorph.get());
stream->writeCharSimple('[');
bool first = true;
auto curr = list->getFirstNode();
while(curr != nullptr){
auto value = curr->getData();
if(value || serializer->getConfig()->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
serializer->serialize(stream, curr->getData());
}
curr = curr->getNext();
}
stream->writeCharSimple(']');
}
void Serializer2::serializeFieldsMap(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto map = static_cast<AbstractFieldsMap*>(polymorph.get());
stream->writeCharSimple('{');
bool first = true;
auto curr = map->getFirstEntry();
while(curr != nullptr){
auto value = curr->getValue();
if(value || serializer->getConfig()->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
auto key = curr->getKey();
serializeString(stream, key->getData(), key->getSize());
stream->writeSimple(":", 1);
serializer->serialize(stream, curr->getValue());
}
curr = curr->getNext();
}
stream->writeCharSimple('}');
}
void Serializer2::serializeObject(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
stream->writeCharSimple('{');
bool first = true;
auto fields = polymorph.valueType->properties->getList();
Object* object = static_cast<Object*>(polymorph.get());
for (auto const& field : fields) {
auto value = field->get(object);
if(value || serializer->getConfig()->includeNullFields) {
(first) ? first = false : stream->writeSimple(",", 1);
serializeString(stream, (p_char8)field->name, std::strlen(field->name));
stream->writeSimple(":", 1);
serializer->serialize(stream, value);
}
}
stream->writeCharSimple('}');
}
void Serializer2::serialize(data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph)
{
auto id = polymorph.valueType->classId.id;
auto& method = m_methods[id];
if(method) {
(*method)(this, stream, polymorph);
} else {
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serialize()]: "
"Error. No serialize method for type '" + std::string(polymorph.valueType->classId.name) + "'");
}
}
const std::shared_ptr<Serializer2::Config>& Serializer2::getConfig() {
return m_config;
}
}}}}

View File

@ -1,166 +0,0 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef oatpp_parser_json_mapping_Serializer2_hpp
#define oatpp_parser_json_mapping_Serializer2_hpp
#include "oatpp/parser/json/Beautifier.hpp"
#include "oatpp/core/data/mapping/type/ListMap.hpp"
#include "oatpp/core/data/mapping/type/List.hpp"
#include "oatpp/core/data/mapping/type/Object.hpp"
#include "oatpp/core/data/mapping/type/Primitive.hpp"
#include "oatpp/core/data/mapping/type/Type.hpp"
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
#include "oatpp/core/parser/Caret.hpp"
#include "oatpp/core/collection/LinkedList.hpp"
#include "oatpp/core/Types.hpp"
#include <vector>
namespace oatpp { namespace parser { namespace json { namespace mapping {
/**
* Json Serializer.
* Serializes oatpp DTO object to json. See [Data Transfer Object(DTO) component](https://oatpp.io/docs/components/dto/).
*/
class Serializer2 {
public:
typedef oatpp::data::mapping::type::Type Type;
typedef oatpp::data::mapping::type::Type::Property Property;
typedef oatpp::data::mapping::type::Type::Properties Properties;
typedef oatpp::data::mapping::type::Object Object;
typedef oatpp::String String;
template<class T>
using PolymorphicWrapper = data::mapping::type::PolymorphicWrapper<T>;
typedef oatpp::data::mapping::type::AbstractObjectWrapper AbstractObjectWrapper;
typedef oatpp::data::mapping::type::List<AbstractObjectWrapper> AbstractList;
typedef oatpp::data::mapping::type::ListMap<String, AbstractObjectWrapper> AbstractFieldsMap;
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<Config> createShared(){
return std::make_shared<Config>();
}
/**
* Include fields with value == nullptr into serialized json.
*/
bool includeNullFields = true;
/**
* If `true` - insert string `"<unknown-type>"` in json field value in case unknown field found.
* Fail if `false`.
* Known types for this serializer are:<br>
* (String, Int8, Int16, Int32, Int64, Float32, Float64, Boolean, DTOs, List, Fields).
*/
bool throwOnUnknownTypes = true;
/**
* Use JSON Beautifier.
*/
bool useBeautifier = false;
/**
* Beautifier Indent.
*/
oatpp::String beautifierIndent = " ";
/**
* Beautifier new line.
*/
oatpp::String beautifierNewLine = "\n";
};
public:
typedef void (*SerializerMethod)(Serializer2*,
data::stream::ConsistentOutputStream*,
const data::mapping::type::AbstractObjectWrapper&);
private:
template<class T>
static void serializePrimitive(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph){
if(polymorph){
stream->writeAsString(static_cast<typename T::ObjectType*>(polymorph.get())->getValue());
} else {
stream->writeSimple("null", 4);
}
}
static void serializeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size);
static void serializeString(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
static void serializeList(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
static void serializeFieldsMap(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
static void serializeObject(Serializer2* serializer,
data::stream::ConsistentOutputStream* stream,
const data::mapping::type::AbstractObjectWrapper& polymorph);
private:
std::vector<SerializerMethod> m_methods;
std::shared_ptr<Config> m_config;
public:
Serializer2(const std::shared_ptr<Config>& config = std::make_shared<Config>());
void setSerializerMethod(const data::mapping::type::ClassId& classId, SerializerMethod method);
void serialize(data::stream::ConsistentOutputStream* stream, const data::mapping::type::AbstractObjectWrapper& polymorph);
const std::shared_ptr<Config>& getConfig();
};
}}}}
#endif /* oatpp_parser_json_mapping_Serializer2_hpp */

View File

@ -25,7 +25,7 @@
#include "DTOMapperPerfTest.hpp"
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/parser/json/mapping/Serializer2.hpp"
#include "oatpp/parser/json/mapping/Serializer.hpp"
#include "oatpp/core/data/stream/BufferStream.hpp"
@ -38,7 +38,7 @@ namespace oatpp { namespace test { namespace parser { namespace json { namespace
namespace {
typedef oatpp::parser::json::mapping::Serializer2 Serializer;
typedef oatpp::parser::json::mapping::Serializer Serializer;
typedef oatpp::parser::json::mapping::Deserializer Deserializer;
#include OATPP_CODEGEN_BEGIN(DTO)
@ -72,7 +72,7 @@ void DTOMapperPerfTest::onRun() {
v_int32 numIterations = 1000000;
auto serializer2 = std::make_shared<oatpp::parser::json::mapping::Serializer2>();
auto serializer2 = std::make_shared<oatpp::parser::json::mapping::Serializer>();
auto mapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
auto test1 = Test1::createTestInstance();
@ -80,7 +80,7 @@ void DTOMapperPerfTest::onRun() {
OATPP_LOGV(TAG, "json='%s'", (const char*) test1_Text->getData());
{
PerformanceChecker checker("Serializer2");
PerformanceChecker checker("Serializer");
for(v_int32 i = 0; i < numIterations; i ++) {
oatpp::data::stream::BufferOutputStream stream;
serializer2->serialize(&stream, test1);

View File

@ -35,7 +35,7 @@ namespace {
typedef oatpp::data::mapping::type::Object DTO;
typedef oatpp::parser::Caret ParsingCaret;
typedef oatpp::parser::json::mapping::Serializer2 Serializer;
typedef oatpp::parser::json::mapping::Serializer Serializer;
typedef oatpp::parser::json::mapping::Deserializer Deserializer;
class EmptyDto : public DTO {