Merge pull request #936 from oatpp/#879_data_tree

#879 data tree
This commit is contained in:
Leonid Stryzhevskyi 2024-05-08 16:54:40 -07:00 committed by GitHub
commit ad486b0f6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
104 changed files with 4430 additions and 1750 deletions

View File

@ -69,14 +69,16 @@ OATPP_ASSERT(decoded == data)
| `oatpp/core/concurrency/*` | `oatpp/concurrency/*` |
| `oatpp/core/provider/*` | `oatpp/provider/*` |
| `oatpp/core/data/*` | `oatpp/data/*` |
| `oatpp/core/parser/*` | `oatpp/utils/parser*` |
| `oatpp/core/parser/*` | `oatpp/utils/parser/*` |
| `oatpp/data/mapping/type/*` | `oatpp/data/type/*` |
### Namespaces
| old namespace | new namespace |
|-----------------------------------|----------------------|
| `oatpp::parser::json::*` | `oatpp::json::*` |
| `oatpp::parser::json::mapping::*` | `oatpp::json::*` |
| `oatpp::algorithm::CRC` | `oatpp::utils::CRC32`|
| old namespace | new namespace |
|-----------------------------------|------------------------|
| `oatpp::parser::json::*` | `oatpp::json::*` |
| `oatpp::parser::json::mapping::*` | `oatpp::json::*` |
| `oatpp::algorithm::CRC` | `oatpp::utils::CRC32` |
| `oatpp::data::mapping::type::*` | `oatpp::data::type::*` |

View File

@ -70,30 +70,14 @@ add_library(oatpp
oatpp/data/buffer/Processor.hpp
oatpp/data/mapping/ObjectMapper.cpp
oatpp/data/mapping/ObjectMapper.hpp
oatpp/data/mapping/ObjectToTreeMapper.cpp
oatpp/data/mapping/ObjectToTreeMapper.hpp
oatpp/data/mapping/Tree.cpp
oatpp/data/mapping/Tree.hpp
oatpp/data/mapping/TreeToObjectMapper.cpp
oatpp/data/mapping/TreeToObjectMapper.hpp
oatpp/data/mapping/TypeResolver.cpp
oatpp/data/mapping/TypeResolver.hpp
oatpp/data/mapping/type/Any.cpp
oatpp/data/mapping/type/Any.hpp
oatpp/data/mapping/type/Collection.hpp
oatpp/data/mapping/type/Enum.cpp
oatpp/data/mapping/type/Enum.hpp
oatpp/data/mapping/type/List.cpp
oatpp/data/mapping/type/List.hpp
oatpp/data/mapping/type/Map.hpp
oatpp/data/mapping/type/Object.cpp
oatpp/data/mapping/type/Object.hpp
oatpp/data/mapping/type/PairList.cpp
oatpp/data/mapping/type/PairList.hpp
oatpp/data/mapping/type/Primitive.cpp
oatpp/data/mapping/type/Primitive.hpp
oatpp/data/mapping/type/Type.cpp
oatpp/data/mapping/type/Type.hpp
oatpp/data/mapping/type/UnorderedMap.cpp
oatpp/data/mapping/type/UnorderedMap.hpp
oatpp/data/mapping/type/UnorderedSet.cpp
oatpp/data/mapping/type/UnorderedSet.hpp
oatpp/data/mapping/type/Vector.cpp
oatpp/data/mapping/type/Vector.hpp
oatpp/data/resource/File.cpp
oatpp/data/resource/File.hpp
oatpp/data/resource/InMemoryData.cpp
@ -116,6 +100,30 @@ add_library(oatpp
oatpp/data/stream/Stream.hpp
oatpp/data/stream/StreamBufferedProxy.cpp
oatpp/data/stream/StreamBufferedProxy.hpp
oatpp/data/type/Any.cpp
oatpp/data/type/Any.hpp
oatpp/data/type/Collection.hpp
oatpp/data/type/Enum.cpp
oatpp/data/type/Enum.hpp
oatpp/data/type/List.cpp
oatpp/data/type/List.hpp
oatpp/data/type/Map.hpp
oatpp/data/type/Object.cpp
oatpp/data/type/Object.hpp
oatpp/data/type/PairList.cpp
oatpp/data/type/PairList.hpp
oatpp/data/type/Primitive.cpp
oatpp/data/type/Primitive.hpp
oatpp/data/type/Tree.cpp
oatpp/data/type/Tree.hpp
oatpp/data/type/Type.cpp
oatpp/data/type/Type.hpp
oatpp/data/type/UnorderedMap.cpp
oatpp/data/type/UnorderedMap.hpp
oatpp/data/type/UnorderedSet.cpp
oatpp/data/type/UnorderedSet.hpp
oatpp/data/type/Vector.cpp
oatpp/data/type/Vector.hpp
oatpp/encoding/Base64.cpp
oatpp/encoding/Base64.hpp
oatpp/encoding/Hex.cpp

View File

@ -25,161 +25,168 @@
#ifndef oatpp_Types_hpp
#define oatpp_Types_hpp
#include "oatpp/data/mapping/type/Object.hpp"
#include "oatpp/data/type/Object.hpp"
#include "oatpp/data/mapping/Tree.hpp"
namespace oatpp {
/**
* &id:oatpp::data::mapping::type::Type;.
* &id:oatpp::data::type::Type;.
*/
typedef oatpp::data::mapping::type::Type Type;
typedef oatpp::data::type::Type Type;
/**
* &id:oatpp::data::mapping::type::ClassId;.
* &id:oatpp::data::type::ClassId;.
*/
typedef oatpp::data::mapping::type::ClassId ClassId;
typedef oatpp::data::type::ClassId ClassId;
/**
* ObjectWrapper.
*/
template <class T, class Clazz = oatpp::data::mapping::type::__class::Void>
using ObjectWrapper = oatpp::data::mapping::type::ObjectWrapper<T, Clazz>;
template <class T, class Clazz = oatpp::data::type::__class::Void>
using ObjectWrapper = oatpp::data::type::ObjectWrapper<T, Clazz>;
/**
* Mapping enabled &id:oatpp::data::mapping::Tree;
* `mapping::Tree` and `type::Tree` are inter-mappable;
*/
typedef oatpp::data::type::Tree Tree;
/**
* ObjectWrapper over the `void*`.
*/
typedef oatpp::data::mapping::type::Void Void;
typedef oatpp::data::type::Void Void;
/**
* `Any` - container for mapping-enabled types.
* &id:oatpp::data::mapping::type::Any;
* &id:oatpp::data::type::Any;
*/
typedef oatpp::data::mapping::type::Any Any;
typedef oatpp::data::type::Any Any;
/**
* Mapping-Enabled String type. &id:oatpp::data::mapping::type::String; <br>
* Mapping-Enabled String type. &id:oatpp::data::type::String; <br>
* For `oatpp::String` methods see `std::string`
*/
typedef oatpp::data::mapping::type::String String;
typedef oatpp::data::type::String String;
/**
* Mapping-Enabled 8-bits int. Can hold nullptr value. &id:oatpp::data::mapping::type::Int8;
* Mapping-Enabled 8-bits int. Can hold nullptr value. &id:oatpp::data::type::Int8;
*/
typedef oatpp::data::mapping::type::Int8 Int8;
typedef oatpp::data::type::Int8 Int8;
/**
* Mapping-Enabled 8-bits unsigned int. Can hold nullptr value. &id:oatpp::data::mapping::type::UInt8;
* Mapping-Enabled 8-bits unsigned int. Can hold nullptr value. &id:oatpp::data::type::UInt8;
*/
typedef oatpp::data::mapping::type::UInt8 UInt8;
typedef oatpp::data::type::UInt8 UInt8;
/**
* Mapping-Enabled 16-bits int. Can hold nullptr value. &id:oatpp::data::mapping::type::Int16;
* Mapping-Enabled 16-bits int. Can hold nullptr value. &id:oatpp::data::type::Int16;
*/
typedef oatpp::data::mapping::type::Int16 Int16;
typedef oatpp::data::type::Int16 Int16;
/**
* Mapping-Enabled 16-bits unsigned int. Can hold nullptr value. &id:oatpp::data::mapping::type::UInt16;
* Mapping-Enabled 16-bits unsigned int. Can hold nullptr value. &id:oatpp::data::type::UInt16;
*/
typedef oatpp::data::mapping::type::UInt16 UInt16;
typedef oatpp::data::type::UInt16 UInt16;
/**
* Mapping-Enabled 32-bits int. Can hold nullptr value. &id:oatpp::data::mapping::type::Int32;
* Mapping-Enabled 32-bits int. Can hold nullptr value. &id:oatpp::data::type::Int32;
*/
typedef oatpp::data::mapping::type::Int32 Int32;
typedef oatpp::data::type::Int32 Int32;
/**
* Mapping-Enabled 32-bits unsigned int. Can hold nullptr value. &id:oatpp::data::mapping::type::UInt32;
* Mapping-Enabled 32-bits unsigned int. Can hold nullptr value. &id:oatpp::data::type::UInt32;
*/
typedef oatpp::data::mapping::type::UInt32 UInt32;
typedef oatpp::data::type::UInt32 UInt32;
/**
* Mapping-Enabled 64-bits int. Can hold nullptr value. &id:oatpp::data::mapping::type::Int64;
* Mapping-Enabled 64-bits int. Can hold nullptr value. &id:oatpp::data::type::Int64;
*/
typedef oatpp::data::mapping::type::Int64 Int64;
typedef oatpp::data::type::Int64 Int64;
/**
* Mapping-Enabled 64-bits unsigned int. Can hold nullptr value. &id:oatpp::data::mapping::type::UInt64;
* Mapping-Enabled 64-bits unsigned int. Can hold nullptr value. &id:oatpp::data::type::UInt64;
*/
typedef oatpp::data::mapping::type::UInt64 UInt64;
typedef oatpp::data::type::UInt64 UInt64;
/**
* Mapping-Enabled 32-bits float. Can hold nullptr value. &id:oatpp::data::mapping::type::Float32;
* Mapping-Enabled 32-bits float. Can hold nullptr value. &id:oatpp::data::type::Float32;
*/
typedef oatpp::data::mapping::type::Float32 Float32;
typedef oatpp::data::type::Float32 Float32;
/**
* Mapping-Enabled 64-bits float (double). Can hold nullptr value. &id:oatpp::data::mapping::type::Float64;
* Mapping-Enabled 64-bits float (double). Can hold nullptr value. &id:oatpp::data::type::Float64;
*/
typedef oatpp::data::mapping::type::Float64 Float64;
typedef oatpp::data::type::Float64 Float64;
/**
* Mapping-Enabled Boolean. Can hold nullptr value. &id:oatpp::data::mapping::type::Boolean;
* Mapping-Enabled Boolean. Can hold nullptr value. &id:oatpp::data::type::Boolean;
*/
typedef oatpp::data::mapping::type::Boolean Boolean;
typedef oatpp::data::type::Boolean Boolean;
/**
* Base class for all Object-like Mapping-enabled structures. &id:oatpp::data::mapping::type::BaseObject;
* Base class for all Object-like Mapping-enabled structures. &id:oatpp::data::type::BaseObject;
*/
typedef oatpp::data::mapping::type::BaseObject BaseObject;
typedef oatpp::data::type::BaseObject BaseObject;
/**
* Base class for all DTO objects. &id:oatpp::data::mapping::type::DTO;
* Base class for all DTO objects. &id:oatpp::data::type::DTO;
*/
typedef oatpp::data::mapping::type::DTO DTO;
typedef oatpp::data::type::DTO DTO;
/**
* Mapping-Enabled DTO Object. &id:oatpp::data::mapping::type::DTOWrapper;
* Mapping-Enabled DTO Object. &id:oatpp::data::type::DTOWrapper;
*/
template <class T>
using Object = oatpp::data::mapping::type::DTOWrapper<T>;
using Object = oatpp::data::type::DTOWrapper<T>;
/**
* Mapping-Enabled Enum. &id:oatpp::data::mapping::type::Enum;
* Mapping-Enabled Enum. &id:oatpp::data::type::Enum;
*/
template <class T>
using Enum = oatpp::data::mapping::type::Enum<T>;
using Enum = oatpp::data::type::Enum<T>;
/**
* Mapping-Enabled Vector. &id:oatpp::data::mapping::type::Vector;
* Mapping-Enabled Vector. &id:oatpp::data::type::Vector;
*/
template <class T>
using Vector = oatpp::data::mapping::type::Vector<T>;
using Vector = oatpp::data::type::Vector<T>;
/**
* Abstract Vector.
*/
typedef oatpp::data::mapping::type::AbstractVector AbstractVector;
typedef oatpp::data::type::AbstractVector AbstractVector;
/**
* Mapping-Enabled List. &id:oatpp::data::mapping::type::List;
* Mapping-Enabled List. &id:oatpp::data::type::List;
*/
template <class T>
using List = oatpp::data::mapping::type::List<T>;
using List = oatpp::data::type::List<T>;
/**
* Abstract List.
*/
typedef oatpp::data::mapping::type::AbstractList AbstractList;
typedef oatpp::data::type::AbstractList AbstractList;
/**
* Mapping-Enabled UnorderedSet. &id:oatpp::data::mapping::type::UnorderedSet;
* Mapping-Enabled UnorderedSet. &id:oatpp::data::type::UnorderedSet;
*/
template <class T>
using UnorderedSet = oatpp::data::mapping::type::UnorderedSet<T>;
using UnorderedSet = oatpp::data::type::UnorderedSet<T>;
/**
* Abstract UnorderedSet.
*/
typedef oatpp::data::mapping::type::AbstractUnorderedSet AbstractUnorderedSet;
typedef oatpp::data::type::AbstractUnorderedSet AbstractUnorderedSet;
/**
* Mapping-Enabled PairList<Key, Value>. &id:oatpp::data::mapping::type::PairList;
* Mapping-Enabled PairList<Key, Value>. &id:oatpp::data::type::PairList;
*/
template <class Key, class Value>
using PairList = oatpp::data::mapping::type::PairList<Key, Value>;
using PairList = oatpp::data::type::PairList<Key, Value>;
/**
* Mapping-Enabled PairList<String, Value>. &id:oatpp::data::mapping::type::PairList;
* Mapping-Enabled PairList<String, Value>. &id:oatpp::data::type::PairList;
*/
template <class Value>
using Fields = oatpp::PairList<String, Value>;
@ -190,13 +197,13 @@ namespace oatpp {
typedef Fields<oatpp::Void> AbstractFields;
/**
* Mapping-Enabled UnorderedMap<Key, Value>. &id:oatpp::data::mapping::type::UnorderedMap;.
* Mapping-Enabled UnorderedMap<Key, Value>. &id:oatpp::data::type::UnorderedMap;.
*/
template <class Key, class Value>
using UnorderedMap = oatpp::data::mapping::type::UnorderedMap<Key, Value>;
using UnorderedMap = oatpp::data::type::UnorderedMap<Key, Value>;
/**
* Mapping-Enabled UnorderedMap<String, Value>. &id:oatpp::data::mapping::type::UnorderedMap;.
* Mapping-Enabled UnorderedMap<String, Value>. &id:oatpp::data::type::UnorderedMap;.
*/
template <class Value>
using UnorderedFields = oatpp::UnorderedMap<String, Value>;

View File

@ -38,7 +38,7 @@
* *For details see:*
* <ul>
* <li>[Data Transfer Object(DTO) component](https://oatpp.io/docs/components/dto/)</li>
* <li>&id:oatpp::data::mapping::type::Object;</li>
* <li>&id:oatpp::data::type::Object;</li>
* </ul>
*/

View File

@ -38,7 +38,7 @@
* *For details see:*
* <ul>
* <li>[Data Transfer Object(DTO) component](https://oatpp.io/docs/components/dto/)</li>
* <li>&id:oatpp::data::mapping::type::Object;</li>
* <li>&id:oatpp::data::type::Object;</li>
* </ul>
*/

View File

@ -227,7 +227,7 @@ const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request->readBodyToString();
#define OATPP_MACRO_API_CONTROLLER_BODY_STRING_INFO(TYPE, PARAM_LIST) \
info->body.name = OATPP_MACRO_FIRSTARG_STR PARAM_LIST; \
info->body.required = true; \
info->body.type = oatpp::data::mapping::type::__class::String::getType(); \
info->body.type = oatpp::data::type::__class::String::getType(); \
if(getDefaultObjectMapper()) { \
info->bodyContentType = getDefaultObjectMapper()->getInfo().http_content_type; \
}

View File

@ -26,17 +26,17 @@
// Defaults
/**
* Codegen macro to be used in classes extending &id:oatpp::data::mapping::type::Object; to generate required fields/methods/constructors for DTO object.
* Codegen macro to be used in classes extending &id:oatpp::data::type::Object; to generate required fields/methods/constructors for DTO object.
* @param TYPE_NAME - name of the DTO class.
* @param TYPE_EXTEND - name of the parent DTO class. If DTO extends &id:oatpp::data::mapping::type::Object; TYPE_EXETENDS should be `Object`.
* @param TYPE_EXTEND - name of the parent DTO class. If DTO extends &id:oatpp::data::type::Object; TYPE_EXETENDS should be `Object`.
*/
#define DTO_INIT(TYPE_NAME, TYPE_EXTEND) \
template<class __Z__T__PARAM> \
friend class oatpp::data::mapping::type::__class::Object; \
friend class oatpp::data::type::__class::Object; \
public: \
typedef TYPE_NAME Z__CLASS; \
typedef TYPE_EXTEND Z__CLASS_EXTENDED; \
typedef oatpp::data::mapping::type::DTOWrapper<Z__CLASS> Wrapper; \
typedef oatpp::data::type::DTOWrapper<Z__CLASS> Wrapper; \
private: \
\
static const oatpp::Type* getParentType() { \
@ -47,8 +47,8 @@ private: \
return #TYPE_NAME; \
} \
\
static oatpp::data::mapping::type::BaseObject::Properties* Z__CLASS_GET_FIELDS_MAP(){ \
static oatpp::data::mapping::type::BaseObject::Properties map = oatpp::data::mapping::type::BaseObject::Properties(); \
static oatpp::data::type::BaseObject::Properties* Z__CLASS_GET_FIELDS_MAP(){ \
static oatpp::data::type::BaseObject::Properties map = oatpp::data::type::BaseObject::Properties(); \
return &map; \
} \
\
@ -70,9 +70,9 @@ static v_int64 Z__PROPERTY_OFFSET_##NAME() { \
return reinterpret_cast<v_int64>(ptr) - reinterpret_cast<v_int64>(buffer); \
} \
\
static oatpp::data::mapping::type::BaseObject::Property* Z__PROPERTY_SINGLETON_##NAME() { \
static oatpp::data::mapping::type::BaseObject::Property* property = \
new oatpp::data::mapping::type::BaseObject::Property(Z__PROPERTY_OFFSET_##NAME(), \
static oatpp::data::type::BaseObject::Property* Z__PROPERTY_SINGLETON_##NAME() { \
static oatpp::data::type::BaseObject::Property* property = \
new oatpp::data::type::BaseObject::Property(Z__PROPERTY_OFFSET_##NAME(), \
#NAME, \
TYPE::Class::getType()); \
return property; \
@ -101,9 +101,9 @@ static v_int64 Z__PROPERTY_OFFSET_##NAME() { \
return reinterpret_cast<v_int64>(ptr) - reinterpret_cast<v_int64>(buffer); \
} \
\
static oatpp::data::mapping::type::BaseObject::Property* Z__PROPERTY_SINGLETON_##NAME() { \
static oatpp::data::mapping::type::BaseObject::Property* property = \
new oatpp::data::mapping::type::BaseObject::Property(Z__PROPERTY_OFFSET_##NAME(), \
static oatpp::data::type::BaseObject::Property* Z__PROPERTY_SINGLETON_##NAME() { \
static oatpp::data::type::BaseObject::Property* property = \
new oatpp::data::type::BaseObject::Property(Z__PROPERTY_OFFSET_##NAME(), \
QUALIFIER, \
TYPE::Class::getType()); \
return property; \
@ -142,7 +142,7 @@ static bool Z__PROPERTY_INIT_##NAME(int, ...) { \
return true; \
} \
\
static void Z__PROPERTY_ADD_INFO_##NAME(oatpp::data::mapping::type::BaseObject::Property::Info* info)
static void Z__PROPERTY_ADD_INFO_##NAME(oatpp::data::type::BaseObject::Property::Info* info)
#define DTO_FIELD_TYPE_SELECTOR(NAME) \

View File

@ -52,7 +52,7 @@ OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (NAME, __VA_
#define OATPP_MACRO_DTO_ENUM_VALUE_1(NAME, VAL) \
{ \
oatpp::data::mapping::type::EnumValueInfo<EnumType> entry = {EnumType::NAME, index ++, #NAME, nullptr}; \
oatpp::data::type::EnumValueInfo<EnumType> entry = {EnumType::NAME, index ++, #NAME, nullptr}; \
info.byName.insert({#NAME, entry}); \
info.byValue.insert({static_cast<v_uint64>(EnumType::NAME), entry}); \
info.byIndex.push_back(entry); \
@ -60,7 +60,7 @@ OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (NAME, __VA_
#define OATPP_MACRO_DTO_ENUM_VALUE_2(NAME, VAL, QUALIFIER) \
{ \
oatpp::data::mapping::type::EnumValueInfo<EnumType> entry = {EnumType::NAME, index ++, QUALIFIER, nullptr}; \
oatpp::data::type::EnumValueInfo<EnumType> entry = {EnumType::NAME, index ++, QUALIFIER, nullptr}; \
info.byName.insert({QUALIFIER, entry}); \
info.byValue.insert({static_cast<v_uint64>(EnumType::NAME), entry}); \
info.byIndex.push_back(entry); \
@ -68,7 +68,7 @@ OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (NAME, __VA_
#define OATPP_MACRO_DTO_ENUM_VALUE_3(NAME, VAL, QUALIFIER, DESCRIPTION) \
{ \
oatpp::data::mapping::type::EnumValueInfo<EnumType> entry = {EnumType::NAME, index ++, QUALIFIER, DESCRIPTION}; \
oatpp::data::type::EnumValueInfo<EnumType> entry = {EnumType::NAME, index ++, QUALIFIER, DESCRIPTION}; \
info.byName.insert({QUALIFIER, entry}); \
info.byValue.insert({static_cast<v_uint64>(EnumType::NAME), entry}); \
info.byIndex.push_back(entry); \
@ -95,7 +95,7 @@ enum class NAME : ORDINAL_TYPE {}; \
\
namespace { \
\
class Z__OATPP_ENUM_META_##NAME : public oatpp::data::mapping::type::EnumMeta<NAME> { \
class Z__OATPP_ENUM_META_##NAME : public oatpp::data::type::EnumMeta<NAME> { \
private: \
\
static bool init() { \
@ -128,7 +128,7 @@ enum class NAME : ORDINAL_TYPE { \
) \
}; \
\
class Z__OATPP_ENUM_META_##NAME : public oatpp::data::mapping::type::EnumMeta<NAME> { \
class Z__OATPP_ENUM_META_##NAME : public oatpp::data::type::EnumMeta<NAME> { \
private: \
\
static bool init() { \

View File

@ -28,6 +28,52 @@
namespace oatpp { namespace data { namespace mapping {
void ErrorStack::push(const oatpp::String& error) {
stack.emplace_back(error);
}
void ErrorStack::splice(ErrorStack& errorStack) {
stack.splice(stack.end(), errorStack.stack);
}
oatpp::String ErrorStack::stacktrace() const {
stream::BufferOutputStream ss;
for(auto& s : stack) {
ss << s << "\n";
}
return ss.toString();
}
bool ErrorStack::empty() const {
return stack.empty();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MappingError
MappingError::MappingError(const ErrorStack& errorStack)
: std::runtime_error(errorStack.empty() ? "[oatpp::data::mapping::MappingError]"
: errorStack.stack.front().getValue("<empty-error-stack>"))
, m_stack(errorStack)
{}
MappingError::MappingError(ErrorStack&& errorStack)
: std::runtime_error(errorStack.empty() ? "[oatpp::data::mapping::MappingError]"
: errorStack.stack.front().getValue("<empty-error-stack>"))
, m_stack(std::move(errorStack))
{}
const ErrorStack& MappingError::errorStack() const {
return m_stack;
}
ErrorStack& MappingError::errorStack() {
return m_stack;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ObjectMapper
ObjectMapper::ObjectMapper(const Info& info)
: m_info(info)
{}
@ -38,7 +84,11 @@ const ObjectMapper::Info& ObjectMapper::getInfo() const {
oatpp::String ObjectMapper::writeToString(const type::Void& variant) const {
stream::BufferOutputStream stream;
write(&stream, variant);
ErrorStack errorStack;
write(&stream, variant, errorStack);
if(!errorStack.empty()) {
throw MappingError(std::move(errorStack));
}
return stream.toString();
}

View File

@ -25,8 +25,7 @@
#ifndef oatpp_data_mapping_ObjectMapper_hpp
#define oatpp_data_mapping_ObjectMapper_hpp
#include "type/Object.hpp"
#include "type/Type.hpp"
#include "oatpp/Types.hpp"
#include "oatpp/data/stream/Stream.hpp"
@ -35,6 +34,76 @@
namespace oatpp { namespace data { namespace mapping {
/**
* Error stack
*/
struct ErrorStack {
/**
* stack
*/
std::list<oatpp::String> stack;
/**
* Push error
* @param error
*/
void push(const oatpp::String& error);
/**
* Push all errors from other error stack.
* @param errorStack
*/
void splice(ErrorStack& errorStack);
/**
* Stacktrace as string.
* @return
*/
oatpp::String stacktrace() const;
/**
* Check if error stack is empty.
* @return
*/
bool empty() const;
};
/**
* Mapping error
*/
class MappingError : public std::runtime_error {
private:
ErrorStack m_stack;
public:
/**
* Constructor.
* @param errorStack
*/
MappingError(const ErrorStack& errorStack);
/**
* Constructor.
* @param errorStack
*/
MappingError(ErrorStack&& errorStack);
/**
* Get error stack
* @return - See &id:oatpp::data::mapping::ErrorStack;.
*/
const ErrorStack& errorStack() const;
/**
* Get error stack
* @return - See &id:oatpp::data::mapping::ErrorStack;.
*/
ErrorStack& errorStack();
};
/**
* Abstract ObjectMapper class.
*/
@ -80,24 +149,28 @@ public:
/**
* Serialize object to stream. Implement this method.
* @param stream - &id:oatpp::data::stream::ConsistentOutputStream; to serialize object to.
* @param errorStack - See &id:oatpp::data::mapping::ErrorStack;.
* @param variant - Object to serialize.
*/
virtual void write(data::stream::ConsistentOutputStream* stream, const type::Void& variant) const = 0;
virtual void write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant, ErrorStack& errorStack) const = 0;
/**
* Deserialize object. Implement this method.
* @param caret - &id:oatpp::utils::parser::Caret; over serialized buffer.
* @param type - pointer to object type. See &id:oatpp::data::mapping::type::Type;.
* @param type - pointer to object type. See &id:oatpp::data::type::Type;.
* @param errorStack - See &id:oatpp::data::mapping::ErrorStack;.
* @return - deserialized object wrapped in &id:oatpp::Void;.
*/
virtual mapping::type::Void read(oatpp::utils::parser::Caret& caret, const mapping::type::Type* const type) const = 0;
virtual oatpp::Void read(oatpp::utils::parser::Caret& caret, const oatpp::Type* type, ErrorStack& errorStack) const = 0;
/**
* Serialize object to String.
* @param variant - Object to serialize.
* @return - serialized object as &id:oatpp::String;.
* @throws - &id:oatpp::data::mapping::MappingError;
* @throws - depends on implementation.
*/
oatpp::String writeToString(const type::Void& variant) const;
oatpp::String writeToString(const oatpp::Void& variant) const;
/**
* Deserialize object.
@ -105,12 +178,18 @@ public:
* @tparam Wrapper - ObjectWrapper type.
* @param caret - &id:oatpp::utils::parser::Caret; over serialized buffer.
* @return - deserialized Object.
* @throws - &id:oatpp::data::mapping::MappingError;
* @throws - depends on implementation.
*/
template<class Wrapper>
Wrapper readFromCaret(oatpp::utils::parser::Caret& caret) const {
auto type = Wrapper::Class::getType();
return read(caret, type).template cast<Wrapper>();
ErrorStack errorStack;
const auto& result = read(caret, type, errorStack).template cast<Wrapper>();
if(!errorStack.empty()) {
throw MappingError(std::move(errorStack));
}
return result;
}
/**
@ -118,16 +197,17 @@ public:
* @tparam Wrapper - ObjectWrapper type.
* @param str - serialized data.
* @return - deserialized Object.
* @throws - &id:oatpp::utils::parser::ParsingError;
* @throws - &id:oatpp::data::mapping::MappingError;
* @throws - depends on implementation.
*/
template<class Wrapper>
Wrapper readFromString(const oatpp::String& str) const {
auto type = Wrapper::Class::getType();
oatpp::utils::parser::Caret caret(str);
auto result = read(caret, type).template cast<Wrapper>();
if(caret.hasError()) {
throw oatpp::utils::parser::ParsingError(caret.getErrorMessage(), caret.getErrorCode(), caret.getPosition());
ErrorStack errorStack;
const auto& result = read(caret, type, errorStack).template cast<Wrapper>();
if(!errorStack.empty()) {
throw MappingError(std::move(errorStack));
}
return result;
}

View File

@ -0,0 +1,303 @@
/***************************************************************************
*
* 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 "ObjectToTreeMapper.hpp"
#include "oatpp/data/stream/BufferStream.hpp"
#include "oatpp/utils/Conversion.hpp"
namespace oatpp { namespace data { namespace mapping {
ObjectToTreeMapper::ObjectToTreeMapper() {
m_methods.resize(static_cast<size_t>(data::type::ClassId::getClassCount()), nullptr);
setMapperMethod(data::type::__class::String::CLASS_ID, &ObjectToTreeMapper::mapString);
setMapperMethod(data::type::__class::Tree::CLASS_ID, &ObjectToTreeMapper::mapTree);
setMapperMethod(data::type::__class::Any::CLASS_ID, &ObjectToTreeMapper::mapAny);
setMapperMethod(data::type::__class::Int8::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Int8>);
setMapperMethod(data::type::__class::UInt8::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::UInt8>);
setMapperMethod(data::type::__class::Int16::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Int16>);
setMapperMethod(data::type::__class::UInt16::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::UInt16>);
setMapperMethod(data::type::__class::Int32::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Int32>);
setMapperMethod(data::type::__class::UInt32::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::UInt32>);
setMapperMethod(data::type::__class::Int64::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Int64>);
setMapperMethod(data::type::__class::UInt64::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::UInt64>);
setMapperMethod(data::type::__class::Float32::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Float32>);
setMapperMethod(data::type::__class::Float64::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Float64>);
setMapperMethod(data::type::__class::Boolean::CLASS_ID, &ObjectToTreeMapper::mapPrimitive<oatpp::Boolean>);
setMapperMethod(data::type::__class::AbstractObject::CLASS_ID, &ObjectToTreeMapper::mapObject);
setMapperMethod(data::type::__class::AbstractEnum::CLASS_ID, &ObjectToTreeMapper::mapEnum);
setMapperMethod(data::type::__class::AbstractVector::CLASS_ID, &ObjectToTreeMapper::mapCollection);
setMapperMethod(data::type::__class::AbstractList::CLASS_ID, &ObjectToTreeMapper::mapCollection);
setMapperMethod(data::type::__class::AbstractUnorderedSet::CLASS_ID, &ObjectToTreeMapper::mapCollection);
setMapperMethod(data::type::__class::AbstractPairList::CLASS_ID, &ObjectToTreeMapper::mapMap);
setMapperMethod(data::type::__class::AbstractUnorderedMap::CLASS_ID, &ObjectToTreeMapper::mapMap);
}
void ObjectToTreeMapper::setMapperMethod(const data::type::ClassId& classId, MapperMethod method) {
const auto id = static_cast<v_uint32>(classId.id);
if(id >= m_methods.size()) {
m_methods.resize(id + 1, nullptr);
}
m_methods[id] = method;
}
void ObjectToTreeMapper::map(State& state, const oatpp::Void& polymorph) const
{
auto id = static_cast<v_uint32>(polymorph.getValueType()->classId.id);
auto& method = m_methods[id];
if(method) {
(*method)(this, state, polymorph);
} else {
auto* interpretation = polymorph.getValueType()->findInterpretation(state.config->enabledInterpretations);
if(interpretation) {
map(state, interpretation->toInterpretation(polymorph));
} else {
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::map()]: "
"Error. No serialize method for type '" +
oatpp::String(polymorph.getValueType()->classId.name) + "'");
return;
}
}
}
void ObjectToTreeMapper::mapString(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
if(!polymorph) {
state.tree->setNull();
return;
}
state.tree->setString(oatpp::String(std::static_pointer_cast<std::string>(polymorph.getPtr()), oatpp::String::Class::getType()));
}
void ObjectToTreeMapper::mapTree(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
if(!polymorph) {
state.tree->setNull();
return;
}
auto tree = static_cast<mapping::Tree*>(polymorph.get());
*state.tree = *tree; // copy
}
void ObjectToTreeMapper::mapAny(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
if(!polymorph) {
state.tree->setNull();
return;
}
auto anyHandle = static_cast<data::type::AnyHandle*>(polymorph.get());
mapper->map(state, oatpp::Void(anyHandle->ptr, anyHandle->type));
}
void ObjectToTreeMapper::mapEnum(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
auto polymorphicDispatcher = static_cast<const data::type::__class::AbstractEnum::PolymorphicDispatcher*>(
polymorph.getValueType()->polymorphicDispatcher
);
data::type::EnumInterpreterError e = data::type::EnumInterpreterError::OK;
mapper->map(state, polymorphicDispatcher->toInterpretation(polymorph, e));
if(e == data::type::EnumInterpreterError::OK) {
return;
}
switch(e) {
case data::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapEnum()]: Error. Enum constraint violated - 'NotNull'.");
break;
case data::type::EnumInterpreterError::OK:
case data::type::EnumInterpreterError::TYPE_MISMATCH_ENUM:
case data::type::EnumInterpreterError::TYPE_MISMATCH_ENUM_VALUE:
case data::type::EnumInterpreterError::ENTRY_NOT_FOUND:
default:
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapEnum()]: Error. Can't serialize Enum.");
}
}
void ObjectToTreeMapper::mapCollection(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
if(!polymorph) {
state.tree->setNull();
return;
}
auto dispatcher = static_cast<const data::type::__class::Collection::PolymorphicDispatcher*>(
polymorph.getValueType()->polymorphicDispatcher
);
auto iterator = dispatcher->beginIteration(polymorph);
state.tree->setVector(0);
TreeChildrenOperator childrenOperator(*state.tree);
v_int64 index = 0;
while (!iterator->finished()) {
const auto& value = iterator->get();
if(value || state.config->includeNullFields || state.config->alwaysIncludeNullCollectionElements) {
State nestedState;
nestedState.tree = childrenOperator.putItem({});
nestedState.config = state.config;
mapper->map(nestedState, value);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapCollection()]: index=" + utils::Conversion::int64ToStr(index));
return;
}
}
iterator->next();
index ++;
}
}
void ObjectToTreeMapper::mapMap(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
if(!polymorph) {
state.tree->setNull();
return;
}
auto dispatcher = static_cast<const data::type::__class::Map::PolymorphicDispatcher*>(
polymorph.getValueType()->polymorphicDispatcher
);
auto keyType = dispatcher->getKeyType();
if(keyType->classId != oatpp::String::Class::CLASS_ID){
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapMap()]: Invalid map key. Key should be String");
return;
}
auto iterator = dispatcher->beginIteration(polymorph);
if(polymorph.getValueType()->classId == data::type::__class::AbstractUnorderedMap::CLASS_ID) {
state.tree->setMap({});
} else if(polymorph.getValueType()->classId == data::type::__class::AbstractPairList::CLASS_ID) {
state.tree->setPairs({});
} else {
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapMap()]: Invalid polymorph type");
}
TreeChildrenOperator childrenOperator(*state.tree);
while (!iterator->finished()) {
const auto& value = iterator->getValue();
if(value || state.config->includeNullFields || state.config->alwaysIncludeNullCollectionElements) {
const auto& untypedKey = iterator->getKey();
const auto& key = oatpp::String(std::static_pointer_cast<std::string>(untypedKey.getPtr()));
State nestedState;
nestedState.tree = childrenOperator.putPair(key, {});
nestedState.config = state.config;
mapper->map(nestedState, value);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapMap()]: key='" + key + "'");
return;
}
}
iterator->next();
}
}
void ObjectToTreeMapper::mapObject(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph) {
if(!polymorph) {
state.tree->setNull();
return;
}
auto type = polymorph.getValueType();
auto dispatcher = static_cast<const oatpp::data::type::__class::AbstractObject::PolymorphicDispatcher*>(
type->polymorphicDispatcher
);
auto fields = dispatcher->getProperties()->getList();
auto object = static_cast<oatpp::BaseObject*>(polymorph.get());
state.tree->setMap({});
TreeChildrenOperator childrenOperator(*state.tree);
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<oatpp::Any>();
value = any.retrieve(field->info.typeSelector->selectType(object));
} else {
value = field->get(object);
}
if(field->info.required && value == nullptr) {
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapObject()]: "
"Error. " + std::string(type->nameQualifier) + "::"
+ std::string(field->name) + " is required!");
return;
}
if (value || state.config->includeNullFields || (field->info.required && state.config->alwaysIncludeRequired)) {
State nestedState;
nestedState.tree = childrenOperator.putPair(oatpp::String(field->name), {});
nestedState.config = state.config;
mapper->map(nestedState, value);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::ObjectToTreeMapper::mapObject()]: field='" + oatpp::String(field->name) + "'");
return;
}
}
}
}
}}}

View File

@ -0,0 +1,91 @@
/***************************************************************************
*
* 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_data_mapping_ObjectToTreeMapper_hpp
#define oatpp_data_mapping_ObjectToTreeMapper_hpp
#include "./Tree.hpp"
#include "./ObjectMapper.hpp"
namespace oatpp { namespace data { namespace mapping {
class ObjectToTreeMapper : public base::Countable {
public:
struct Config {
bool includeNullFields = true;
bool alwaysIncludeRequired = false;
bool alwaysIncludeNullCollectionElements = false;
std::vector<std::string> enabledInterpretations = {};
};
public:
struct State {
const Config* config;
Tree* tree;
ErrorStack errorStack;
};
public:
typedef void (*MapperMethod)(const ObjectToTreeMapper*, State&, const oatpp::Void&);
public:
template<class T>
static void mapPrimitive(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph){
(void) mapper;
if(polymorph){
state.tree->setValue<typename T::ObjectType>(* static_cast<typename T::ObjectType*>(polymorph.get()));
} else {
state.tree->setNull();
}
}
static void mapString(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
static void mapTree(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
static void mapAny(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
static void mapEnum(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
static void mapCollection(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
static void mapMap(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
static void mapObject(const ObjectToTreeMapper* mapper, State& state, const oatpp::Void& polymorph);
private:
std::vector<MapperMethod> m_methods;
public:
ObjectToTreeMapper();
void setMapperMethod(const data::type::ClassId& classId, MapperMethod method);
void map(State& state, const oatpp::Void& polymorph) const;
};
}}}
#endif //oatpp_data_mapping_ObjectToTreeMapper_hpp

View File

@ -0,0 +1,964 @@
/***************************************************************************
*
* 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 "Tree.hpp"
#include "oatpp/data/stream/BufferStream.hpp"
namespace oatpp { namespace data { namespace mapping {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tree::Attributes
Tree::Attributes::Attributes()
: m_attributes(nullptr)
{}
Tree::Attributes::Attributes(const Attributes& other)
: m_attributes(other.m_attributes != nullptr ? new std::unordered_map<type::String, type::String>(*other.m_attributes) : nullptr)
{}
Tree::Attributes::Attributes(Attributes&& other) noexcept
: m_attributes(other.m_attributes)
{
other.m_attributes = nullptr;
}
Tree::Attributes& Tree::Attributes::operator = (const Attributes& other) {
if(other.m_attributes) {
if(m_attributes) {
*m_attributes = *other.m_attributes;
} else {
m_attributes = new std::unordered_map<type::String, type::String>(*other.m_attributes);
}
} else {
delete m_attributes;
m_attributes = nullptr;
}
return *this;
}
Tree::Attributes& Tree::Attributes::operator = (Attributes&& other) noexcept {
delete m_attributes;
m_attributes = other.m_attributes;
other.m_attributes = nullptr;
return *this;
}
Tree::Attributes::~Attributes() {
delete m_attributes;
}
bool Tree::Attributes::empty() const {
return m_attributes == nullptr || m_attributes->empty();
}
v_uint64 Tree::Attributes::size() const {
if(m_attributes) {
return m_attributes->size();
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Tree
Tree::Tree()
: m_type(Type::UNDEFINED)
, m_data(0)
{}
Tree::Tree(const Tree& other)
: Tree()
{
setCopy(other);
}
Tree::Tree(Tree&& other) noexcept
: m_type(other.m_type)
, m_data(other.m_data)
, m_attributes(std::move(other.m_attributes))
{
other.m_type = Type::UNDEFINED;
other.m_data = 0;
}
Tree::Tree(const type::String& value)
: Tree()
{
setString(value);
}
Tree::~Tree() {
deleteValueObject();
}
Tree& Tree::operator = (const Tree& other) {
setCopy(other);
return *this;
}
Tree& Tree::operator = (Tree&& other) noexcept {
setMove(std::forward<Tree>(other));
return *this;
}
Tree& Tree::operator = (const type::String& value) {
setString(value);
return *this;
}
void Tree::deleteValueObject() {
switch (m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE:
case Type::INTEGER:
case Type::FLOAT:
case Type::BOOL:
case Type::INT_8:
case Type::UINT_8:
case Type::INT_16:
case Type::UINT_16:
case Type::INT_32:
case Type::UINT_32:
case Type::INT_64:
case Type::UINT_64:
case Type::FLOAT_32:
case Type::FLOAT_64:
break;
case Type::STRING: {
auto data = reinterpret_cast<type::String *>(m_data);
delete data;
break;
}
case Type::VECTOR: {
auto data = reinterpret_cast<std::vector<Tree> *>(m_data);
delete data;
break;
}
case Type::MAP: {
auto data = reinterpret_cast<TreeMap *>(m_data);
delete data;
break;
}
case Type::PAIRS: {
auto data = reinterpret_cast<std::vector<std::pair<type::String, Tree>> *>(m_data);
delete data;
break;
}
default:
// DO-NOTHING
break;
}
}
Tree::operator type::String () {
return getString();
}
Tree& Tree::operator [] (const type::String& key) {
return getMap()[key];
}
const Tree& Tree::operator [] (const type::String& key) const {
return getMap()[key];
}
Tree& Tree::operator [] (v_uint64 index) {
return getVector().at(index);
}
const Tree& Tree::operator [] (v_uint64 index) const {
return getVector().at(index);
}
Tree::Type Tree::getType() const {
return m_type;
}
void Tree::setCopy(const Tree& other) {
deleteValueObject();
m_type = other.m_type;
m_attributes = other.m_attributes;
switch (other.m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE:
break;
case Type::INTEGER:
case Type::FLOAT:
case Type::BOOL:
case Type::INT_8:
case Type::UINT_8:
case Type::INT_16:
case Type::UINT_16:
case Type::INT_32:
case Type::UINT_32:
case Type::INT_64:
case Type::UINT_64:
case Type::FLOAT_32:
case Type::FLOAT_64:
{
m_data = other.m_data;
break;
}
case Type::STRING: {
auto otherData = reinterpret_cast<type::String *>(other.m_data);
if(otherData == nullptr) {
throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'STRING'");
}
auto ptr = new type::String(*otherData);
m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
break;
}
case Type::VECTOR: {
auto otherData = reinterpret_cast<std::vector<Tree> *>(other.m_data);
if(otherData == nullptr) {
throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'VECTOR'");
}
auto ptr = new std::vector<Tree>(*otherData);
m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
break;
}
case Type::MAP: {
auto otherData = reinterpret_cast<TreeMap *>(other.m_data);
if(otherData == nullptr) {
throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'MAP'");
}
auto ptr = new TreeMap(*otherData);
m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
break;
}
case Type::PAIRS: {
auto otherData = reinterpret_cast<std::vector<std::pair<type::String, Tree>> *>(other.m_data);
if(otherData == nullptr) {
throw std::runtime_error("[oatpp::data::mapping::Tree::setCopy()]: other.data is null, other.type is 'PAIRS'");
}
auto ptr = new std::vector<std::pair<type::String, Tree>>(*otherData);
m_data = reinterpret_cast<LARGEST_TYPE>(ptr);
break;
}
default:
m_data = other.m_data;
break;
}
}
void Tree::setMove(Tree&& other) {
deleteValueObject();
m_type = other.m_type;
m_data = other.m_data;
m_attributes = std::move(other.m_attributes);
other.m_type = Type::NULL_VALUE;
other.m_data = 0;
}
void Tree::setNull() {
deleteValueObject();
m_type = Type::NULL_VALUE;
m_data = 0;
}
void Tree::setUndefined() {
deleteValueObject();
m_type = Type::UNDEFINED;
m_data = 0;
}
void Tree::setInteger(v_int64 value) {
deleteValueObject();
m_type = Type::INTEGER;
std::memcpy (&m_data, &value, sizeof(v_int64));
}
void Tree::setFloat(v_float64 value) {
deleteValueObject();
m_type = Type::FLOAT;
std::memcpy (&m_data, &value, sizeof(v_float64));
}
void Tree::setString(const type::String& value) {
deleteValueObject();
m_type = Type::STRING;
auto data = new type::String(value);
m_data = reinterpret_cast<LARGEST_TYPE>(data);
}
void Tree::setVector(const std::vector<Tree>& value) {
deleteValueObject();
m_type = Type::VECTOR;
auto data = new std::vector<Tree>(value);
m_data = reinterpret_cast<LARGEST_TYPE>(data);
}
void Tree::setVector(v_uint64 size) {
deleteValueObject();
m_type = Type::VECTOR;
auto data = new std::vector<Tree>(size);
m_data = reinterpret_cast<LARGEST_TYPE>(data);
}
void Tree::setMap(const TreeMap& value) {
deleteValueObject();
m_type = Type::MAP;
auto data = new TreeMap(value);
m_data = reinterpret_cast<LARGEST_TYPE>(data);
}
void Tree::setPairs(const std::vector<std::pair<type::String, Tree>>& value) {
deleteValueObject();
m_type = Type::PAIRS;
auto data = new std::vector<std::pair<type::String, Tree>>(value);
m_data = reinterpret_cast<LARGEST_TYPE>(data);
}
bool Tree::isNull() const {
return m_type == Type::NULL_VALUE;
}
bool Tree::isUndefined() const {
return m_type == Type::UNDEFINED;
}
bool Tree::isPrimitive() const {
switch (m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE:
return false;
case Type::INTEGER:
case Type::FLOAT:
case Type::BOOL:
case Type::INT_8:
case Type::UINT_8:
case Type::INT_16:
case Type::UINT_16:
case Type::INT_32:
case Type::UINT_32:
case Type::INT_64:
case Type::UINT_64:
case Type::FLOAT_32:
case Type::FLOAT_64:
return true;
case Type::STRING:
case Type::VECTOR:
case Type::MAP:
case Type::PAIRS:
default:
return false;
}
}
v_int32 Tree::primitiveDataSize() const {
switch (m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE:
return -1;
case Type::INTEGER:
case Type::FLOAT: return 8;
case Type::BOOL:
case Type::INT_8:
case Type::UINT_8: return 1;
case Type::INT_16:
case Type::UINT_16: return 2;
case Type::INT_32:
case Type::UINT_32: return 4;
case Type::INT_64:
case Type::UINT_64: return 8;
case Type::FLOAT_32: return 4;
case Type::FLOAT_64: return 8;
case Type::STRING:
case Type::VECTOR:
case Type::MAP:
case Type::PAIRS:
default:
return -1;
}
}
bool Tree::isFloatPrimitive() const {
switch (m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE:
case Type::INTEGER: return false;
case Type::FLOAT: return true;
case Type::BOOL:
case Type::INT_8:
case Type::UINT_8:
case Type::INT_16:
case Type::UINT_16:
case Type::INT_32:
case Type::UINT_32:
case Type::INT_64:
case Type::UINT_64: return false;
case Type::FLOAT_32:
case Type::FLOAT_64: return true;
case Type::STRING:
case Type::VECTOR:
case Type::MAP:
case Type::PAIRS:
default:
return false;
}
}
bool Tree::isIntPrimitive() const {
switch (m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE:
return false;
case Type::INTEGER: return true;
case Type::FLOAT: return false;
case Type::BOOL:
case Type::INT_8:
case Type::UINT_8:
case Type::INT_16:
case Type::UINT_16:
case Type::INT_32:
case Type::UINT_32:
case Type::INT_64:
case Type::UINT_64: return true;
case Type::FLOAT_32:
case Type::FLOAT_64:
case Type::STRING:
case Type::VECTOR:
case Type::MAP:
case Type::PAIRS:
default:
return false;
}
}
v_int64 Tree::getInteger() const {
if(m_type != Type::INTEGER) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getInteger()]: NOT an arbitrary INTEGER.");
}
v_int64 result;
std::memcpy (&result, &m_data, sizeof(v_float64));
return result;
}
v_float64 Tree::getFloat() const {
if(m_type != Type::FLOAT) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getFloat()]: NOT an arbitrary FLOAT.");
}
v_float64 result;
std::memcpy (&result, &m_data, sizeof(v_float64));
return result;
}
const type::String& Tree::getString() const {
if(m_type != Type::STRING) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getString()]: NOT a STRING.");
}
auto data = reinterpret_cast<const type::String*>(m_data);
return *data;
}
const std::vector<Tree>& Tree::getVector() const {
if(m_type != Type::VECTOR) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getVector()]: NOT a VECTOR.");
}
auto data = reinterpret_cast<const std::vector<Tree>*>(m_data);
return *data;
}
const TreeMap& Tree::getMap() const {
if(m_type != Type::MAP) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getMap()]: NOT a MAP.");
}
auto data = reinterpret_cast<const TreeMap*>(m_data);
return *data;
}
const std::vector<std::pair<type::String, Tree>>& Tree::getPairs() const {
if(m_type != Type::PAIRS) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getPairs()]: NOT a PAIRS.");
}
auto data = reinterpret_cast<const std::vector<std::pair<type::String, Tree>>*>(m_data);
return *data;
}
std::vector<Tree>& Tree::getVector() {
if(m_type == Type::UNDEFINED) {
setVector({});
}
if(m_type != Type::VECTOR) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getVector()]: NOT a VECTOR.");
}
auto data = reinterpret_cast<std::vector<Tree>*>(m_data);
return *data;
}
TreeMap& Tree::getMap() {
if(m_type == Type::UNDEFINED) {
setMap({});
}
if(m_type != Type::MAP) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getMap()]: NOT a MAP.");
}
auto data = reinterpret_cast<TreeMap*>(m_data);
return *data;
}
std::vector<std::pair<type::String, Tree>>& Tree::getPairs() {
if(m_type == Type::UNDEFINED) {
setPairs({});
}
if(m_type != Type::PAIRS) {
throw std::runtime_error("[oatpp::data::mapping::Tree::getMap()]: NOT a PAIRS.");
}
auto data = reinterpret_cast<std::vector<std::pair<type::String, Tree>>*>(m_data);
return *data;
}
Tree::Attributes& Tree::attributes() {
return m_attributes;
}
const Tree::Attributes& Tree::attributes() const {
return m_attributes;
}
type::String Tree::debugPrint(v_uint32 indent0, v_uint32 indentDelta, bool firstLineIndent) const {
stream::BufferOutputStream ss;
for(v_uint32 i = 0; i < indent0; i ++) {
ss << " ";
}
type::String indentStr0 = ss.toString();
ss.setCurrentPosition(0);
for(v_uint32 i = 0; i < indentDelta; i ++) {
ss << " ";
}
type::String indentDeltaStr = ss.toString();
ss.setCurrentPosition(0);
if(firstLineIndent) {
ss << indentStr0;
}
switch (m_type) {
case Type::UNDEFINED: {
ss << "undefined";
break;
}
case Type::NULL_VALUE: {
ss << "null";
break;
}
case Type::INTEGER: {
ss << getInteger() << " (integer)";
break;
}
case Type::FLOAT: {
ss << getFloat() << " (float)";
break;
}
case Type::BOOL: {
ss << getValue<bool>() << " (bool)";
break;
}
case Type::INT_8: {
ss << getValue<v_int8>() << " (int_8)";
break;
}
case Type::UINT_8: {
ss << getValue<v_uint8>() << " (uint_8)";
break;
}
case Type::INT_16: {
ss << getValue<v_int16>() << " (int_16)";
break;
}
case Type::UINT_16: {
ss << getValue<v_uint16>() << " (uint_16)";
break;
}
case Type::INT_32: {
ss << getValue<v_int32 >() << " (int_32)";
break;
}
case Type::UINT_32: {
ss << getValue<v_uint32>() << " (uint_32)";
break;
}
case Type::INT_64: {
ss << getValue<v_int64>() << " (int_64)";
break;
}
case Type::UINT_64: {
ss << getValue<v_uint64>() << " (uint_64)";
break;
}
case Type::FLOAT_32: {
ss << getValue<v_float32>() << " (float_32)";
break;
}
case Type::FLOAT_64: {
ss << getValue<v_float64>() << " (float_64)";
break;
}
case Type::STRING: {
ss << "'" << getString() << "'";
break;
}
case Type::VECTOR: {
ss << "VECTOR [\n";
auto& vector = getVector();
for(auto& v : vector) {
ss << v.debugPrint(indent0 + indentDelta, indentDelta) << "\n";
}
ss << indentStr0 << "]";
break;
}
case Type::MAP: {
ss << "MAP {\n";
auto& map = getMap();
for(v_uint32 i = 0; i < map.size(); i ++) {
const auto& node = map[i];
ss << indentStr0 << indentDeltaStr << node.first << ": " << node.second.get().debugPrint(indent0 + indentDelta, indentDelta, false) << "\n";
}
ss << indentStr0 << "}";
break;
}
case Type::PAIRS: {
ss << "PAIRS {\n";
auto& pairs = getPairs();
for(auto& node : pairs) {
ss << indentStr0 << indentDeltaStr << node.first << ": " << node.second.debugPrint(indent0 + indentDelta, indentDelta, false) << "\n";
}
ss << indentStr0 << "}";
break;
}
default:
break;
}
return ss.toString();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TreeMap
TreeMap::TreeMap(const TreeMap& other) {
operator=(other);
}
TreeMap::TreeMap(TreeMap&& other) noexcept {
operator=(std::forward<TreeMap>(other));
}
TreeMap& TreeMap::operator = (const TreeMap& other) {
m_map = other.m_map;
m_order.resize(other.m_order.size());
for(v_uint64 i = 0; i < other.m_order.size(); i ++) {
auto& po = other.m_order[i];
auto& pt = m_order[i];
pt.first = po.first;
pt.second = &m_map.at(po.first.lock());
}
return *this;
}
TreeMap& TreeMap::operator = (TreeMap&& other) noexcept {
m_map = std::move(other.m_map);
m_order = std::move(other.m_order);
for(auto& p : m_order) {
p.second = &m_map.at(p.first.lock());
}
return *this;
}
Tree& TreeMap::operator [] (const type::String& key) {
auto it = m_map.find(key);
if(it == m_map.end()) {
auto& result = m_map[key];
m_order.emplace_back(key.getPtr(), &result);
return result;
}
return it->second;
}
const Tree& TreeMap::operator [] (const type::String& key) const {
auto it = m_map.find(key);
if(it == m_map.end()) {
throw std::runtime_error("[oatpp::data::mapping::Tree::TreeMap::operator[]]: const operator[] can't add items.");
}
return it->second;
}
std::pair<type::String, std::reference_wrapper<Tree>> TreeMap::operator [] (v_uint64 index) {
auto& item = m_order.at(index);
return {item.first.lock(), *item.second};
}
std::pair<type::String, std::reference_wrapper<const Tree>> TreeMap::operator [] (v_uint64 index) const {
auto& item = m_order.at(index);
return {item.first.lock(), *item.second};
}
v_uint64 TreeMap::size() const {
return m_map.size();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TreeChildrenOperator
TreeChildrenOperator::TreeChildrenOperator(Tree& tree)
: TreeChildrenOperator(const_cast<const Tree&>(tree))
{
m_const = false;
}
TreeChildrenOperator::TreeChildrenOperator(const Tree& tree)
: m_vector(nullptr)
, m_map(nullptr)
, m_pairs(nullptr)
{
m_const = true;
if(tree.getType() == Tree::Type::VECTOR) {
m_type = VECTOR;
m_vector = std::addressof(tree.getVector());
} else if(tree.getType() == Tree::Type::MAP) {
m_type = MAP;
m_map = std::addressof(tree.getMap());
} else if(tree.getType() == Tree::Type::PAIRS) {
m_type = PAIRS;
m_pairs = std::addressof(tree.getPairs());
} else {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::TreeChildrenOperator()]: Node type is NOT suppoerted");
}
}
std::pair<type::String, Tree*> TreeChildrenOperator::getPair(v_uint64 index) {
if(m_const) {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getPair()]: Can't operate on CONST tree node");
}
switch (m_type) {
case VECTOR: break;
case MAP: {
const auto& p = (*const_cast<TreeMap*>(m_map))[index];
return {p.first, std::addressof(p.second.get())};
}
case PAIRS: {
auto& p = const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs)->at(index);
return {p.first, &p.second};
}
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getPair()]: Node type doesn't support pairs");
}
std::pair<type::String, const Tree*> TreeChildrenOperator::getPair(v_uint64 index) const {
switch (m_type) {
case VECTOR: break;
case MAP: {
const auto& p = (*m_map)[index];
return {p.first, std::addressof(p.second.get())};
}
case PAIRS: {
auto& p = (*m_pairs)[index];
return {p.first, &p.second};
}
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getPair()]: Node type doesn't support pairs");
}
Tree* TreeChildrenOperator::getItem(v_uint64 index) {
if(m_const) {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getItem()]: Can't operate on CONST tree node");
}
switch (m_type) {
case VECTOR: return std::addressof(const_cast<std::vector<Tree>*>(m_vector)->at(index));
case MAP: return std::addressof((*const_cast<TreeMap*>(m_map))[index].second.get());
case PAIRS: return &const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs)->at(index).second;
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getItem()]: Invalid iterator type");
}
const Tree* TreeChildrenOperator::getItem(v_uint64 index) const {
switch (m_type) {
case VECTOR: return std::addressof(m_vector->at(index));
case MAP: return std::addressof((*m_map)[index].second.get());
case PAIRS: return &m_pairs->at(index).second;
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::getItem()]: Invalid operator type");
}
Tree* TreeChildrenOperator::putPair(const type::String& key, const Tree& tree) {
if(m_const) {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Can't operate on CONST tree node");
}
switch (m_type) {
case VECTOR: break;
case MAP: {
auto& node = (*const_cast<TreeMap*>(m_map))[key];
node = tree;
return std::addressof(node);
}
case PAIRS: {
auto& pairs = *const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs);
pairs.emplace_back(key, tree);
auto& p = pairs.at(pairs.size() - 1);
return std::addressof(p.second);
}
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Node type doesn't support pairs");
}
Tree* TreeChildrenOperator::putPair(const type::String& key, Tree&& tree) {
if(m_const) {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Can't operate on CONST tree node");
}
switch (m_type) {
case VECTOR: break;
case MAP: {
auto& node = (*const_cast<TreeMap*>(m_map))[key];
node = std::forward<Tree>(tree);
return std::addressof(node);
}
case PAIRS: {
auto& pairs = *const_cast<std::vector<std::pair<type::String, Tree>>*>(m_pairs);
pairs.emplace_back(key, std::forward<Tree>(tree));
auto& p = pairs.at(pairs.size() - 1);
return std::addressof(p.second);
}
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putPair()]: Node type doesn't support pairs");
}
Tree* TreeChildrenOperator::putItem(const Tree& tree) {
if(m_const) {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Can't operate on CONST tree node");
}
switch (m_type) {
case VECTOR: {
auto& vector = *const_cast<std::vector<Tree>*>(m_vector);
vector.push_back(tree);
return std::addressof(vector.at(vector.size() - 1));
}
case MAP:
case PAIRS:
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Invalid iterator type");
}
Tree* TreeChildrenOperator::putItem(Tree&& tree) {
if(m_const) {
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Can't operate on CONST tree node");
}
switch (m_type) {
case VECTOR: {
auto& vector = *const_cast<std::vector<Tree>*>(m_vector);
vector.emplace_back(std::forward<Tree>(tree));
return std::addressof(vector.at(vector.size() - 1));
}
case MAP:
case PAIRS:
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::putItem()]: Invalid iterator type");
}
v_uint64 TreeChildrenOperator::size() const {
switch (m_type) {
case VECTOR: return m_vector->size();
case MAP: return m_map->size();
case PAIRS: return m_pairs->size();
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::TreeChildrenOperator::size()]: Invalid operator type");
}
}}}

View File

@ -0,0 +1,380 @@
/***************************************************************************
*
* 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_data_mapping_Tree_hpp
#define oatpp_data_mapping_Tree_hpp
#include "oatpp/data/type/Object.hpp"
namespace oatpp { namespace data { namespace mapping {
class TreeMap;
class Tree {
public:
enum class Type : v_int32 {
UNDEFINED = 0,
NULL_VALUE = 1,
INTEGER = 2,
FLOAT = 3,
BOOL = 4,
INT_8 = 5,
UINT_8 = 6,
INT_16 = 7,
UINT_16 = 8,
INT_32 = 9,
UINT_32 = 10,
INT_64 = 11,
UINT_64 = 12,
FLOAT_32 = 13,
FLOAT_64 = 14,
STRING = 15,
VECTOR = 16,
MAP = 17,
PAIRS = 18
};
template<typename T>
struct NodePrimitiveType {
};
public:
class Attributes {
private:
std::unordered_map<type::String, type::String>* m_attributes;
public:
Attributes();
Attributes(const Attributes& other);
Attributes(Attributes&& other) noexcept;
Attributes& operator = (const Attributes& other);
Attributes& operator = (Attributes&& other) noexcept;
~Attributes();
bool empty() const;
v_uint64 size() const;
};
private:
typedef v_uint64 LARGEST_TYPE;
private:
void deleteValueObject();
private:
Type m_type;
LARGEST_TYPE m_data;
Attributes m_attributes;
public:
Tree();
Tree(const Tree& other);
Tree(Tree&& other) noexcept;
template<typename T, typename enabled = typename NodePrimitiveType<T>::value_type>
explicit Tree (T value)
: Tree()
{
setValue<T>(value);
}
explicit Tree(const type::String& value);
~Tree();
Tree& operator = (const Tree& other);
Tree& operator = (Tree&& other) noexcept;
template<typename T, typename enabled = typename NodePrimitiveType<T>::value_type>
Tree& operator = (T value) {
setValue<T>(value);
return *this;
}
Tree& operator = (const type::String& value);
template <typename T, typename enabled = typename NodePrimitiveType<T>::value_type>
operator T () const {
switch (m_type) {
case Type::UNDEFINED:
case Type::NULL_VALUE: break;
case Type::INTEGER: return static_cast<T>(getInteger());
case Type::FLOAT: return static_cast<T>(getFloat());
case Type::BOOL: return static_cast<T>(getValue<bool>());
case Type::INT_8: return static_cast<T>(getValue<v_int8>());
case Type::UINT_8: return static_cast<T>(getValue<v_uint8>());
case Type::INT_16: return static_cast<T>(getValue<v_int16>());
case Type::UINT_16: return static_cast<T>(getValue<v_uint16>());
case Type::INT_32: return static_cast<T>(getValue<v_int32>());
case Type::UINT_32: return static_cast<T>(getValue<v_uint32>());
case Type::INT_64: return static_cast<T>(getValue<v_int64>());
case Type::UINT_64: return static_cast<T>(getValue<v_uint64>());
case Type::FLOAT_32: return static_cast<T>(getValue<v_float32>());
case Type::FLOAT_64: return static_cast<T>(getValue<v_float64>());
case Type::STRING:
case Type::VECTOR:
case Type::MAP:
case Type::PAIRS:
default:
break;
}
throw std::runtime_error("[oatpp::data::mapping::Tree::operator T ()]: Value is NOT a Primitive type.");
}
operator type::String ();
Tree& operator [] (const type::String& key);
const Tree& operator [] (const type::String& key) const;
Tree& operator [] (v_uint64 index);
const Tree& operator [] (v_uint64 index) const;
Type getType() const;
void setCopy(const Tree& other);
void setMove(Tree&& other);
template <typename T>
void setValue(T value) {
deleteValueObject();
m_type = NodePrimitiveType<T>::type;
m_data = 0;
std::memcpy (&m_data, &value, sizeof(T));
}
template<typename T>
T getValue() const {
if(m_type != NodePrimitiveType<T>::type) {
throw std::runtime_error(std::string("[oatpp::data::mapping::Tree::getValue()]: NOT a ") + NodePrimitiveType<T>::name);
}
T result;
std::memcpy (&result, &m_data, sizeof(T));
return result;
}
void setNull();
void setUndefined();
void setInteger(v_int64 value);
void setFloat(v_float64 value);
void setString(const type::String& value);
void setVector(const std::vector<Tree>& value);
void setVector(v_uint64 size);
void setMap(const TreeMap& value);
void setPairs(const std::vector<std::pair<type::String, Tree>>& value);
bool isNull() const;
bool isUndefined() const;
bool isPrimitive() const;
v_int32 primitiveDataSize() const;
bool isFloatPrimitive() const;
bool isIntPrimitive() const;
v_int64 getInteger() const;
v_float64 getFloat() const;
const type::String& getString() const;
const std::vector<Tree>& getVector() const;
const TreeMap& getMap() const;
const std::vector<std::pair<type::String, Tree>>& getPairs() const;
std::vector<Tree>& getVector();
TreeMap& getMap();
std::vector<std::pair<type::String, Tree>>& getPairs();
Attributes& attributes();
const Attributes& attributes() const;
type::String debugPrint(v_uint32 indent0 = 0, v_uint32 indentDelta = 2, bool firstLineIndent = true) const;
};
class TreeMap {
private:
std::unordered_map<type::String, Tree> m_map;
std::vector<std::pair<std::weak_ptr<std::string>, Tree*>> m_order;
public:
TreeMap() = default;
TreeMap(const TreeMap& other);
TreeMap(TreeMap&& other) noexcept;
TreeMap& operator = (const TreeMap& other);
TreeMap& operator = (TreeMap&& other) noexcept;
Tree& operator [] (const type::String& key);
const Tree& operator [] (const type::String& key) const;
std::pair<type::String, std::reference_wrapper<Tree>> operator [] (v_uint64 index);
std::pair<type::String, std::reference_wrapper<const Tree>> operator [] (v_uint64 index) const;
v_uint64 size() const;
};
class TreeChildrenOperator {
private:
enum IteratorType {
VECTOR,
MAP,
PAIRS
};
private:
const std::vector<Tree>* m_vector;
const TreeMap* m_map;
const std::vector<std::pair<type::String, Tree>>* m_pairs;
private:
bool m_const;
IteratorType m_type;
public:
explicit TreeChildrenOperator(Tree& tree);
explicit TreeChildrenOperator(const Tree& tree);
std::pair<type::String, Tree*> getPair(v_uint64 index);
std::pair<type::String, const Tree*> getPair(v_uint64 index) const;
Tree* getItem(v_uint64 index);
const Tree* getItem(v_uint64 index) const;
Tree* putPair(const type::String& key, const Tree& tree);
Tree* putPair(const type::String& key, Tree&& tree);
Tree* putItem(const Tree& tree);
Tree* putItem(Tree&& tree);
v_uint64 size() const;
};
//////////////////////////////////////////////////////
// Tree::NodePrimitiveType
template<>
struct Tree::NodePrimitiveType<bool> {
static constexpr Type type = Type::BOOL;
static constexpr const char* name = "BOOL";
typedef bool value_type;
};
template<>
struct Tree::NodePrimitiveType<v_int8> {
static constexpr Type type = Type::INT_8;
static constexpr const char* name = "INT_8";
typedef v_int8 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_uint8> {
static constexpr Type type = Type::UINT_8;
static constexpr const char* name = "UINT_8";
typedef v_uint8 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_int16> {
static constexpr Type type = Type::INT_16;
static constexpr const char* name = "INT_16";
typedef v_int16 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_uint16> {
static constexpr Type type = Type::UINT_16;
static constexpr const char* name = "UINT_16";
typedef v_uint16 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_int32> {
static constexpr Type type = Type::INT_32;
static constexpr const char* name = "INT_32";
typedef v_int32 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_uint32> {
static constexpr Type type = Type::UINT_32;
static constexpr const char* name = "UINT_32";
typedef v_uint32 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_int64> {
static constexpr Type type = Type::INT_64;
static constexpr const char* name = "INT_64";
typedef v_int64 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_uint64> {
static constexpr Type type = Type::UINT_64;
static constexpr const char* name = "UINT_64";
typedef v_uint64 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_float32> {
static constexpr Type type = Type::FLOAT_32;
static constexpr const char* name = "FLOAT_32";
typedef v_float32 value_type;
};
template<>
struct Tree::NodePrimitiveType<v_float64> {
static constexpr Type type = Type::FLOAT_64;
static constexpr const char* name = "FLOAT_64";
typedef v_float64 value_type;
};
}}}
#endif //oatpp_data_mapping_Tree_hpp

View File

@ -0,0 +1,369 @@
/***************************************************************************
*
* 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 "TreeToObjectMapper.hpp"
#include "oatpp/data/stream/BufferStream.hpp"
#include "oatpp/utils/Conversion.hpp"
namespace oatpp { namespace data { namespace mapping {
TreeToObjectMapper::TreeToObjectMapper() {
m_methods.resize(static_cast<size_t>(data::type::ClassId::getClassCount()), nullptr);
setMapperMethod(data::type::__class::String::CLASS_ID, &TreeToObjectMapper::mapString);
setMapperMethod(data::type::__class::Tree::CLASS_ID, &TreeToObjectMapper::mapTree);
setMapperMethod(data::type::__class::Any::CLASS_ID, &TreeToObjectMapper::mapAny);
setMapperMethod(data::type::__class::Int8::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Int8>);
setMapperMethod(data::type::__class::UInt8::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::UInt8>);
setMapperMethod(data::type::__class::Int16::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Int16>);
setMapperMethod(data::type::__class::UInt16::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::UInt16>);
setMapperMethod(data::type::__class::Int32::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Int32>);
setMapperMethod(data::type::__class::UInt32::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::UInt32>);
setMapperMethod(data::type::__class::Int64::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Int64>);
setMapperMethod(data::type::__class::UInt64::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::UInt64>);
setMapperMethod(data::type::__class::Float32::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Float32>);
setMapperMethod(data::type::__class::Float64::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Float64>);
setMapperMethod(data::type::__class::Boolean::CLASS_ID, &TreeToObjectMapper::mapPrimitive<oatpp::Boolean>);
setMapperMethod(data::type::__class::AbstractObject::CLASS_ID, &TreeToObjectMapper::mapObject);
setMapperMethod(data::type::__class::AbstractEnum::CLASS_ID, &TreeToObjectMapper::mapEnum);
setMapperMethod(data::type::__class::AbstractVector::CLASS_ID, &TreeToObjectMapper::mapCollection);
setMapperMethod(data::type::__class::AbstractList::CLASS_ID, &TreeToObjectMapper::mapCollection);
setMapperMethod(data::type::__class::AbstractUnorderedSet::CLASS_ID, &TreeToObjectMapper::mapCollection);
setMapperMethod(data::type::__class::AbstractPairList::CLASS_ID, &TreeToObjectMapper::mapMap);
setMapperMethod(data::type::__class::AbstractUnorderedMap::CLASS_ID, &TreeToObjectMapper::mapMap);
}
void TreeToObjectMapper::setMapperMethod(const data::type::ClassId& classId, MapperMethod method) {
const auto id = static_cast<v_uint32>(classId.id);
if(id >= m_methods.size()) {
m_methods.resize(id + 1, nullptr);
}
m_methods[id] = method;
}
oatpp::Void TreeToObjectMapper::map(State& state, const Type* type) const {
auto id = static_cast<v_uint32>(type->classId.id);
auto& method = m_methods[id];
if(method) {
return (*method)(this, state, type);
} else {
auto* interpretation = type->findInterpretation(state.config->enabledInterpretations);
if(interpretation) {
return interpretation->fromInterpretation(map(state, interpretation->getInterpretationType()));
}
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::map()]: "
"Error. No map method for type '" + std::string(type->classId.name) + "'");
return nullptr;
}
}
const Type* TreeToObjectMapper::guessType(const Tree& node) {
switch (node.getType()) {
case Tree::Type::UNDEFINED:
case Tree::Type::NULL_VALUE: return nullptr;
case Tree::Type::INTEGER: return Int64::Class::getType();
case Tree::Type::FLOAT: return Float64::Class::getType();
case Tree::Type::BOOL: return Boolean::Class::getType();
case Tree::Type::INT_8: return Int8::Class::getType();
case Tree::Type::UINT_8: return UInt8::Class::getType();
case Tree::Type::INT_16: return Int16::Class::getType();
case Tree::Type::UINT_16: return UInt16::Class::getType();
case Tree::Type::INT_32: return Int32::Class::getType();
case Tree::Type::UINT_32: return UInt32::Class::getType();
case Tree::Type::INT_64: return Int64::Class::getType();
case Tree::Type::UINT_64: return UInt64::Class::getType();
case Tree::Type::FLOAT_32: return Float32::Class::getType();
case Tree::Type::FLOAT_64: return Float64::Class::getType();
case Tree::Type::STRING: return String::Class::getType();
case Tree::Type::VECTOR: return Vector<oatpp::Any>::Class::getType();
case Tree::Type::MAP: return Fields<oatpp::Any>::Class::getType();
case Tree::Type::PAIRS: return Fields<oatpp::Any>::Class::getType();
default: return nullptr;
}
}
oatpp::Void TreeToObjectMapper::mapString(const TreeToObjectMapper* mapper, State& state, const Type* type) {
(void) mapper;
(void) type;
if(state.tree->getType() == Tree::Type::STRING) {
return state.tree->getString();
}
if(state.tree->isNull()){
return oatpp::Void(String::Class::getType());
}
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapString()]: Node is NOT a STRING");
return nullptr;
}
oatpp::Void TreeToObjectMapper::mapTree(const TreeToObjectMapper* mapper, State& state, const Type* type) {
(void) type;
(void) mapper;
return oatpp::Tree(std::make_shared<mapping::Tree>(*state.tree), oatpp::Tree::Class::getType());
}
oatpp::Void TreeToObjectMapper::mapAny(const TreeToObjectMapper* mapper, State& state, const Type* type) {
(void) type;
if(state.tree->isNull()){
return oatpp::Void(Any::Class::getType());
} else {
const Type* const fieldType = guessType(*state.tree);
if(fieldType != nullptr) {
auto fieldValue = mapper->map(state, fieldType);
auto anyHandle = std::make_shared<data::type::AnyHandle>(fieldValue.getPtr(), fieldValue.getValueType());
return oatpp::Void(anyHandle, Any::Class::getType());
}
}
return oatpp::Void(Any::Class::getType());
}
oatpp::Void TreeToObjectMapper::mapEnum(const TreeToObjectMapper* mapper, State& state, const Type* type) {
auto polymorphicDispatcher = static_cast<const data::type::__class::AbstractEnum::PolymorphicDispatcher*>(
type->polymorphicDispatcher
);
data::type::EnumInterpreterError e = data::type::EnumInterpreterError::OK;
const auto& value = mapper->map(state, polymorphicDispatcher->getInterpretationType());
if(!state.errorStack.empty()) {
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapEnum()]");
return nullptr;
}
const auto& result = polymorphicDispatcher->fromInterpretation(value, e);
if(e == data::type::EnumInterpreterError::OK) {
return result;
}
switch(e) {
case data::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapEnum()]: Error. Enum constraint violated - 'NotNull'.");
break;
case data::type::EnumInterpreterError::OK:
case data::type::EnumInterpreterError::TYPE_MISMATCH_ENUM:
case data::type::EnumInterpreterError::TYPE_MISMATCH_ENUM_VALUE:
case data::type::EnumInterpreterError::ENTRY_NOT_FOUND:
default:
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapEnum()]: Error. Can't map Enum.");
}
return nullptr;
}
oatpp::Void TreeToObjectMapper::mapCollection(const TreeToObjectMapper* mapper, State& state, const Type* type) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
auto dispatcher = static_cast<const data::type::__class::Collection::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto collection = dispatcher->createObject();
auto itemType = dispatcher->getItemType();
const TreeChildrenOperator childrenOperator(*state.tree);
v_uint64 childrenCount = childrenOperator.size();
State nestedState;
nestedState.config = state.config;
for(v_uint64 index = 0; index < childrenCount; index ++) {
nestedState.tree = childrenOperator.getItem(index);
auto item = mapper->map(nestedState, itemType);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapCollection()]: index=" + utils::Conversion::uint64ToStr(index));
return nullptr;
}
dispatcher->addItem(collection, item);
}
return collection;
}
oatpp::Void TreeToObjectMapper::mapMap(const TreeToObjectMapper* mapper, State& state, const Type* type) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
auto dispatcher = static_cast<const data::type::__class::Map::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto map = dispatcher->createObject();
auto keyType = dispatcher->getKeyType();
if(keyType->classId != oatpp::String::Class::CLASS_ID){
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapMap()]: Invalid map key. Key should be String");
return nullptr;
}
auto valueType = dispatcher->getValueType();
const TreeChildrenOperator childrenOperator(*state.tree);
v_uint64 childrenCount = childrenOperator.size();
State nestedState;
nestedState.config = state.config;
for(v_uint64 i = 0; i < childrenCount; i ++) {
const auto& pair = childrenOperator.getPair(i);
nestedState.tree = pair.second;
auto item = mapper->map(nestedState, valueType);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapMap()]: key='" + pair.first + "'");
return nullptr;
}
dispatcher->addItem(map, pair.first, item);
}
return map;
}
oatpp::Void TreeToObjectMapper::mapObject(const TreeToObjectMapper* mapper, State& state, const Type* type) {
if(state.tree->isNull()){
return oatpp::Void(type);
}
auto dispatcher = static_cast<const oatpp::data::type::__class::AbstractObject::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto object = dispatcher->createObject();
const auto& fieldsMap = dispatcher->getProperties()->getMap();
std::vector<std::pair<oatpp::BaseObject::Property*, const Tree*>> polymorphs;
const TreeChildrenOperator childrenOperator(*state.tree);
v_uint64 childrenCount = childrenOperator.size();
for(v_uint64 i = 0; i < childrenCount; i ++) {
const auto& pair = childrenOperator.getPair(i);
auto fieldIterator = fieldsMap.find(pair.first);
if(fieldIterator != fieldsMap.end()){
auto field = fieldIterator->second;
if(field->info.typeSelector && field->type == oatpp::Any::Class::getType()) {
polymorphs.emplace_back(field, pair.second); // store polymorphs for later processing.
} else {
State nestedState;
nestedState.tree = pair.second;
nestedState.config = state.config;
auto value = mapper->map(nestedState, field->type);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapObject()]: field='" + pair.first + "'");
return nullptr;
}
if(field->info.required && value == nullptr) {
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapObject()]: Error. " +
oatpp::String(type->nameQualifier) + "::" +
oatpp::String(field->name) + " is required!");
return nullptr;
}
field->set(static_cast<oatpp::BaseObject *>(object.get()), value);
}
} else if (!state.config->allowUnknownFields) {
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapObject()]: Error. Unknown field '" + pair.first + "'");
return nullptr;
}
}
for(auto& p : polymorphs) {
auto selectedType = p.first->info.typeSelector->selectType(static_cast<oatpp::BaseObject *>(object.get()));
State nestedState;
nestedState.tree = p.second;
nestedState.config = state.config;
auto value = mapper->map(nestedState, selectedType);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapObject()]: field='" + oatpp::String(p.first->name) + "'");
return nullptr;
}
if(p.first->info.required && value == nullptr) {
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapObject()]: Error. " +
oatpp::String(type->nameQualifier) + "::" +
oatpp::String(p.first->name) + " is required!");
return nullptr;
}
oatpp::Any any(value);
p.first->set(static_cast<oatpp::BaseObject *>(object.get()), oatpp::Void(any.getPtr(), p.first->type));
}
return object;
}
}}}

View File

@ -0,0 +1,95 @@
/***************************************************************************
*
* 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_data_mapping_TreeToObjectMapper_hpp
#define oatpp_data_mapping_TreeToObjectMapper_hpp
#include "./Tree.hpp"
#include "./ObjectMapper.hpp"
namespace oatpp { namespace data { namespace mapping {
class TreeToObjectMapper : public base::Countable {
public:
struct Config {
bool allowUnknownFields = true;
std::vector<std::string> enabledInterpretations = {};
};
public:
struct State {
const Config* config;
const Tree* tree;
ErrorStack errorStack;
};
public:
typedef oatpp::Void (*MapperMethod)(const TreeToObjectMapper*, State&, const Type* const);
public:
template<class T>
static oatpp::Void mapPrimitive(const TreeToObjectMapper* mapper, State& state, const Type* const type){
(void) mapper;
(void) type;
if(state.tree->isPrimitive()) {
return T(state.tree->operator typename T::UnderlyingType());
}
if(state.tree->isNull()) {
return oatpp::Void(T::Class::getType());
}
state.errorStack.push("[oatpp::data::mapping::TreeToObjectMapper::mapPrimitive()]: Value is NOT a Primitive type");
return nullptr;
}
static const Type* guessType(const Tree& node);
static oatpp::Void mapString(const TreeToObjectMapper* mapper, State& state, const Type* type);
static oatpp::Void mapTree(const TreeToObjectMapper* mapper, State& state, const Type* type);
static oatpp::Void mapAny(const TreeToObjectMapper* mapper, State& state, const Type* type);
static oatpp::Void mapEnum(const TreeToObjectMapper* mapper, State& state, const Type* type);
static oatpp::Void mapCollection(const TreeToObjectMapper* mapper, State& state, const Type* type);
static oatpp::Void mapMap(const TreeToObjectMapper* mapper, State& state, const Type* type);
static oatpp::Void mapObject(const TreeToObjectMapper* mapper, State& state, const Type* type);
private:
std::vector<MapperMethod> m_methods;
public:
TreeToObjectMapper();
void setMapperMethod(const data::type::ClassId& classId, MapperMethod method);
oatpp::Void map(State& state, const Type* type) const;
};
}}}
#endif //oatpp_data_mapping_TreeToObjectMapper_hpp

View File

@ -28,37 +28,37 @@ namespace oatpp { namespace data { namespace mapping {
TypeResolver::TypeResolver() {
m_knownClasses.resize(static_cast<size_t>(data::mapping::type::ClassId::getClassCount()), false);
m_knownClasses.resize(static_cast<size_t>(data::type::ClassId::getClassCount()), false);
addKnownClasses({
data::mapping::type::__class::String::CLASS_ID,
data::mapping::type::__class::Any::CLASS_ID,
data::type::__class::String::CLASS_ID,
data::type::__class::Any::CLASS_ID,
data::mapping::type::__class::Int8::CLASS_ID,
data::mapping::type::__class::UInt8::CLASS_ID,
data::type::__class::Int8::CLASS_ID,
data::type::__class::UInt8::CLASS_ID,
data::mapping::type::__class::Int16::CLASS_ID,
data::mapping::type::__class::UInt16::CLASS_ID,
data::type::__class::Int16::CLASS_ID,
data::type::__class::UInt16::CLASS_ID,
data::mapping::type::__class::Int32::CLASS_ID,
data::mapping::type::__class::UInt32::CLASS_ID,
data::type::__class::Int32::CLASS_ID,
data::type::__class::UInt32::CLASS_ID,
data::mapping::type::__class::Int64::CLASS_ID,
data::mapping::type::__class::UInt64::CLASS_ID,
data::type::__class::Int64::CLASS_ID,
data::type::__class::UInt64::CLASS_ID,
data::mapping::type::__class::Float32::CLASS_ID,
data::mapping::type::__class::Float64::CLASS_ID,
data::mapping::type::__class::Boolean::CLASS_ID,
data::type::__class::Float32::CLASS_ID,
data::type::__class::Float64::CLASS_ID,
data::type::__class::Boolean::CLASS_ID,
data::mapping::type::__class::AbstractObject::CLASS_ID,
data::mapping::type::__class::AbstractEnum::CLASS_ID,
data::type::__class::AbstractObject::CLASS_ID,
data::type::__class::AbstractEnum::CLASS_ID,
data::mapping::type::__class::AbstractVector::CLASS_ID,
data::mapping::type::__class::AbstractList::CLASS_ID,
data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID,
data::type::__class::AbstractVector::CLASS_ID,
data::type::__class::AbstractList::CLASS_ID,
data::type::__class::AbstractUnorderedSet::CLASS_ID,
data::mapping::type::__class::AbstractPairList::CLASS_ID,
data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID
data::type::__class::AbstractPairList::CLASS_ID,
data::type::__class::AbstractUnorderedMap::CLASS_ID
});
}
@ -85,7 +85,7 @@ bool TypeResolver::isKnownClass(const type::ClassId& classId) const {
return false;
}
bool TypeResolver::isKnownType(const type::Type* type) const {
bool TypeResolver::isKnownType(const oatpp::Type* type) const {
if (type != nullptr) {
return isKnownClass(type->classId);
}
@ -100,7 +100,7 @@ const std::vector<std::string>& TypeResolver::getEnabledInterpretations() const
return m_enabledInterpretations;
}
const type::Type* TypeResolver::resolveType(const type::Type* type, Cache& cache) const {
const oatpp::Type* TypeResolver::resolveType(const oatpp::Type* type, Cache& cache) const {
if(type == nullptr) {
return nullptr;
@ -155,7 +155,7 @@ type::Void TypeResolver::resolveValue(const type::Void& value, Cache& cache) con
}
const type::Type* TypeResolver::findPropertyType(const type::Type* baseType,
const oatpp::Type* TypeResolver::findPropertyType(const oatpp::Type* baseType,
const std::vector<std::string>& path,
v_uint32 pathPosition,
Cache& cache) const
@ -228,7 +228,7 @@ type::Void TypeResolver::findPropertyValue(const type::Void& baseObject,
}
const type::Type* TypeResolver::resolveObjectPropertyType(const type::Type* objectType,
const oatpp::Type* TypeResolver::resolveObjectPropertyType(const oatpp::Type* objectType,
const std::vector<std::string>& path,
Cache& cache) const
{

View File

@ -25,7 +25,7 @@
#ifndef oatpp_data_mapping_TypeResolver_hpp
#define oatpp_data_mapping_TypeResolver_hpp
#include "type/Object.hpp"
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping {
@ -42,25 +42,25 @@ public:
/**
* types map.
*/
std::unordered_map<const type::Type*, const type::Type*> types;
std::unordered_map<const oatpp::Type*, const oatpp::Type*> types;
/**
* values by type map.
*/
std::unordered_map<const type::Type*, std::unordered_map<type::Void, type::Void>> values;
std::unordered_map<const oatpp::Type*, std::unordered_map<oatpp::Void, oatpp::Void>> values;
};
private:
const type::Type* findPropertyType(const type::Type* baseType,
const std::vector<std::string>& path,
v_uint32 pathPosition,
Cache& cache) const;
const oatpp::Type* findPropertyType(const oatpp::Type* baseType,
const std::vector<std::string>& path,
v_uint32 pathPosition,
Cache& cache) const;
type::Void findPropertyValue(const type::Void& baseObject,
const std::vector<std::string>& path,
v_uint32 pathPosition,
Cache& cache) const;
oatpp::Void findPropertyValue(const oatpp::Void& baseObject,
const std::vector<std::string>& path,
v_uint32 pathPosition,
Cache& cache) const;
private:
std::vector<bool> m_knownClasses;
@ -82,27 +82,27 @@ public:
* @param classId
* @param isKnown
*/
void setKnownClass(const type::ClassId& classId, bool isKnown);
void setKnownClass(const oatpp::ClassId& classId, bool isKnown);
/**
* Set all mentioned type classes as known.
* @param knownClasses
*/
void addKnownClasses(const std::vector<type::ClassId>& knownClasses);
void addKnownClasses(const std::vector<oatpp::ClassId>& knownClasses);
/**
* Check if type class is known.
* @param classId
* @return
*/
bool isKnownClass(const type::ClassId& classId) const;
bool isKnownClass(const oatpp::ClassId& classId) const;
/**
* Check if type is known.
* @param type
* @return
*/
bool isKnownType(const type::Type* type) const;
bool isKnownType(const oatpp::Type* type) const;
/**
* Set enabled type interpretations.
@ -122,7 +122,7 @@ public:
* @param cache - local cache.
* @return
*/
const type::Type* resolveType(const type::Type* type, Cache& cache) const;
const oatpp::Type* resolveType(const oatpp::Type* type, Cache& cache) const;
/**
* Resolve unknown value according to enabled interpretations.
@ -130,7 +130,7 @@ public:
* @param cache - local cache.
* @return
*/
type::Void resolveValue(const type::Void& value, Cache& cache) const;
oatpp::Void resolveValue(const oatpp::Void& value, Cache& cache) const;
/**
* Traverse object property tree resolving unknown types according to enabled interpretations.
@ -139,7 +139,7 @@ public:
* @param cache - local cache.
* @return - &id:oatpp::Type;. `nullptr` - if couldn't resolve.
*/
const type::Type* resolveObjectPropertyType(const type::Type* objectType,
const oatpp::Type* resolveObjectPropertyType(const oatpp::Type* objectType,
const std::vector<std::string>& path,
Cache& cache) const;
@ -151,9 +151,9 @@ public:
* @return - value as &id:oatpp::Void;. The `valueType` will be set to resolved type
* or to `oatpp::Void::Class::getType()` if couldn't resolve.
*/
type::Void resolveObjectPropertyValue(const type::Void& object,
const std::vector<std::string>& path,
Cache& cache) const;
oatpp::Void resolveObjectPropertyValue(const oatpp::Void& object,
const std::vector<std::string>& path,
Cache& cache) const;
};

View File

@ -41,7 +41,7 @@ namespace oatpp { namespace data { namespace share {
template<typename Key, typename MapType>
class LazyStringMapTemplate {
public:
typedef oatpp::data::mapping::type::String String;
typedef oatpp::data::type::String String;
private:
mutable concurrency::SpinLock m_lock;
mutable bool m_fullyInitialized;

View File

@ -25,7 +25,7 @@
#ifndef oatpp_data_share_MemoryLabel_hpp
#define oatpp_data_share_MemoryLabel_hpp
#include "oatpp/data/mapping/type/Primitive.hpp"
#include "oatpp/data/type/Primitive.hpp"
#include "oatpp/utils/String.hpp"
#include <cstring>
@ -40,7 +40,7 @@ namespace oatpp { namespace data { namespace share {
*/
class MemoryLabel {
public:
typedef oatpp::data::mapping::type::String String;
typedef oatpp::data::type::String String;
protected:
mutable std::shared_ptr<std::string> m_memoryHandle;
mutable const void* m_data;

View File

@ -24,7 +24,7 @@
#include "Any.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId Any::CLASS_ID("Any");
@ -71,7 +71,7 @@ const Type* Any::getStoredType() const {
Void Any::retrieve(const Type* type) const {
if(m_ptr) {
if(!m_ptr->type->extends(type)) {
throw std::runtime_error("[oatpp::data::mapping::type::Any::retrieve()]: Error. The value type doesn't match.");
throw std::runtime_error("[oatpp::data::type::Any::retrieve()]: Error. The value type doesn't match.");
}
return Void(m_ptr->ptr, type);
}
@ -115,4 +115,4 @@ bool Any::operator != (const Any& other) const {
return !operator == (other);
}
}}}}
}}}

View File

@ -22,14 +22,14 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_Any_hpp
#define oatpp_data_mapping_type_Any_hpp
#ifndef oatpp_data_type_Any_hpp
#define oatpp_data_type_Any_hpp
#include "./Type.hpp"
#include "oatpp/base/Countable.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -117,7 +117,7 @@ public:
/**
* Get `Type` of the stored object.
* @return - &id:oatpp::data::mapping::type::Type;.
* @return - &id:oatpp::data::type::Type;.
*/
const Type* getStoredType() const;
@ -160,6 +160,6 @@ public:
};
}}}}
}}}
#endif //oatpp_data_mapping_type_Any_hpp
#endif //oatpp_data_type_Any_hpp

View File

@ -22,13 +22,13 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_Collection_hpp
#define oatpp_data_mapping_type_Collection_hpp
#ifndef oatpp_data_type_Collection_hpp
#define oatpp_data_type_Collection_hpp
#include "./Type.hpp"
#include <unordered_set>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -196,6 +196,6 @@ struct Collection::Inserter<std::unordered_set<ItemType>, ItemType> {
}
}}}}
}}}
#endif //oatpp_data_mapping_type_Collection_hpp
#endif //oatpp_data_type_Collection_hpp

View File

@ -24,10 +24,10 @@
#include "Enum.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId AbstractEnum::CLASS_ID("Enum");
}
}}}}
}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_Enum_hpp
#define oatpp_data_mapping_type_Enum_hpp
#ifndef oatpp_data_type_Enum_hpp
#define oatpp_data_type_Enum_hpp
#include "./Any.hpp"
#include "./Primitive.hpp"
@ -33,7 +33,7 @@
#include <unordered_map>
#include <vector>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
/**
* Errors of enum interpretation.
@ -53,7 +53,7 @@ enum class EnumInterpreterError : v_int32 {
TYPE_MISMATCH_ENUM = 1,
/**
* Wrong &id:oatpp::data::mapping::type::Primitive; is passed to interpreter.
* Wrong &id:oatpp::data::type::Primitive; is passed to interpreter.
*/
TYPE_MISMATCH_ENUM_VALUE = 2,
@ -395,7 +395,7 @@ public:
if(it != EnumMeta<T>::getInfo()->byName.end()) {
return it->second;
}
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByName()]: Error. Entry not found.");
throw std::runtime_error("[oatpp::data::type::Enum::getEntryByName()]: Error. Entry not found.");
}
/**
@ -409,7 +409,7 @@ public:
if(it != EnumMeta<T>::getInfo()->byValue.end()) {
return it->second;
}
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByValue()]: Error. Entry not found.");
throw std::runtime_error("[oatpp::data::type::Enum::getEntryByValue()]: Error. Entry not found.");
}
/**
@ -423,7 +423,7 @@ public:
if(it != EnumMeta<T>::getInfo()->byValue.end()) {
return it->second;
}
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByUnderlyingValue()]: Error. Entry not found.");
throw std::runtime_error("[oatpp::data::type::Enum::getEntryByUnderlyingValue()]: Error. Entry not found.");
}
/**
@ -436,7 +436,7 @@ public:
if(index >= 0 && index < EnumMeta<T>::getInfo()->byIndex.size()) {
return EnumMeta<T>::getInfo()->byIndex[index];
}
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByIndex()]: Error. Entry not found.");
throw std::runtime_error("[oatpp::data::type::Enum::getEntryByIndex()]: Error. Entry not found.");
}
/**
@ -608,7 +608,7 @@ namespace __class {
type::EnumInterpreterError error = type::EnumInterpreterError::OK;
result.push_back(type::Any(toInterpretation(EnumOW(e.value), error)));
if(error != type::EnumInterpreterError::OK) {
throw std::runtime_error("[oatpp::data::mapping::type::__class::Enum<T, Interpreter>::getInterpretedEnum()]: Unknown error.");
throw std::runtime_error("[oatpp::data::type::__class::Enum<T, Interpreter>::getInterpretedEnum()]: Unknown error.");
}
}
@ -638,14 +638,14 @@ namespace __class {
}
}}}}
}}}
namespace std {
template<class T, class I>
struct hash <oatpp::data::mapping::type::EnumObjectWrapper<T, I>> {
struct hash <oatpp::data::type::EnumObjectWrapper<T, I>> {
typedef oatpp::data::mapping::type::EnumObjectWrapper<T, I> argument_type;
typedef oatpp::data::type::EnumObjectWrapper<T, I> argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const &e) const noexcept {
@ -657,4 +657,4 @@ namespace std {
}
#endif // oatpp_data_mapping_type_Enum_hpp
#endif // oatpp_data_type_Enum_hpp

View File

@ -24,10 +24,10 @@
#include "./List.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId AbstractList::CLASS_ID("List");
}
}}}}
}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_List_hpp
#define oatpp_data_mapping_type_List_hpp
#ifndef oatpp_data_type_List_hpp
#define oatpp_data_type_List_hpp
#include "./Collection.hpp"
#include "./Type.hpp"
@ -31,7 +31,7 @@
#include <list>
#include <initializer_list>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -125,6 +125,6 @@ namespace __class {
}
}}}}
}}}
#endif // oatpp_data_mapping_type_List_hpp
#endif // oatpp_data_type_List_hpp

View File

@ -22,13 +22,13 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_Map_hpp
#define oatpp_data_mapping_type_Map_hpp
#ifndef oatpp_data_type_Map_hpp
#define oatpp_data_type_Map_hpp
#include "./Type.hpp"
#include <list>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -219,6 +219,6 @@ struct Map::Inserter<std::list<std::pair<KeyType, ValueType>>, KeyType, ValueTyp
}
}}}}
}}}
#endif //oatpp_data_mapping_type_Map_hpp
#endif //oatpp_data_type_Map_hpp

View File

@ -24,7 +24,7 @@
#include "./Object.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BaseObject
@ -97,7 +97,7 @@ namespace __class {
}
const mapping::type::Type* DTO::getParentType() {
const type::Type* DTO::getParentType() {
return nullptr;
}
@ -105,8 +105,8 @@ const char* DTO::Z__CLASS_TYPE_NAME() {
return "DTO";
}
oatpp::data::mapping::type::BaseObject::Properties* DTO::Z__CLASS_GET_FIELDS_MAP() {
static data::mapping::type::BaseObject::Properties map;
oatpp::data::type::BaseObject::Properties* DTO::Z__CLASS_GET_FIELDS_MAP() {
static data::type::BaseObject::Properties map;
return &map;
}
@ -115,4 +115,4 @@ BaseObject::Properties* DTO::Z__CLASS_EXTEND(BaseObject::Properties* properties,
return properties;
}
}}}}
}}}

View File

@ -27,6 +27,7 @@
#include "./Type.hpp"
#include "./Tree.hpp"
#include "./Any.hpp"
#include "./Primitive.hpp"
#include "./Enum.hpp"
@ -40,7 +41,7 @@
#include <type_traits>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
/**
* Base class of all object-like mapping-enabled structures ex.: oatpp::DTO.
@ -188,7 +189,7 @@ public:
/**
* Get properties as unordered map for random access.
* @return reference to std::unordered_map of std::string to &id:oatpp::data::mapping::type::BaseObject::Property;*.
* @return reference to std::unordered_map of std::string to &id:oatpp::data::type::BaseObject::Property;*.
*/
const std::unordered_map<std::string, Property*>& getMap() const {
return m_map;
@ -196,7 +197,7 @@ public:
/**
* Get properties in ordered way.
* @return std::list of &id:oatpp::data::mapping::type::BaseObject::Property;*.
* @return std::list of &id:oatpp::data::type::BaseObject::Property;*.
*/
const std::list<Property*>& getList() const {
return m_list;
@ -302,7 +303,7 @@ namespace __class {
/**
* Get type describing this class.
* @return - &id:oatpp::data::mapping::type::Type;
* @return - &id:oatpp::data::type::Type;
*/
static Type* getType() {
static Type* type = createType();
@ -422,46 +423,46 @@ private:
typedef DTO Z__CLASS;
typedef DTO Z__CLASS_EXTENDED;
public:
typedef oatpp::data::mapping::type::Void Void;
typedef oatpp::data::mapping::type::Any Any;
typedef oatpp::data::mapping::type::String String;
typedef oatpp::data::mapping::type::Int8 Int8;
typedef oatpp::data::mapping::type::UInt8 UInt8;
typedef oatpp::data::mapping::type::Int16 Int16;
typedef oatpp::data::mapping::type::UInt16 UInt16;
typedef oatpp::data::mapping::type::Int32 Int32;
typedef oatpp::data::mapping::type::UInt32 UInt32;
typedef oatpp::data::mapping::type::Int64 Int64;
typedef oatpp::data::mapping::type::UInt64 UInt64;
typedef oatpp::data::mapping::type::Float32 Float32;
typedef oatpp::data::mapping::type::Float64 Float64;
typedef oatpp::data::mapping::type::Boolean Boolean;
typedef oatpp::data::type::Void Void;
typedef oatpp::data::type::Any Any;
typedef oatpp::data::type::String String;
typedef oatpp::data::type::Int8 Int8;
typedef oatpp::data::type::UInt8 UInt8;
typedef oatpp::data::type::Int16 Int16;
typedef oatpp::data::type::UInt16 UInt16;
typedef oatpp::data::type::Int32 Int32;
typedef oatpp::data::type::UInt32 UInt32;
typedef oatpp::data::type::Int64 Int64;
typedef oatpp::data::type::UInt64 UInt64;
typedef oatpp::data::type::Float32 Float32;
typedef oatpp::data::type::Float64 Float64;
typedef oatpp::data::type::Boolean Boolean;
template <class T>
using Object = DTOWrapper<T>;
template <class T>
using Enum = oatpp::data::mapping::type::Enum<T>;
using Enum = oatpp::data::type::Enum<T>;
template <class T>
using Vector = oatpp::data::mapping::type::Vector<T>;
using Vector = oatpp::data::type::Vector<T>;
template <class T>
using UnorderedSet = oatpp::data::mapping::type::UnorderedSet<T>;
using UnorderedSet = oatpp::data::type::UnorderedSet<T>;
template <class T>
using List = oatpp::data::mapping::type::List<T>;
using List = oatpp::data::type::List<T>;
template <class Value>
using Fields = oatpp::data::mapping::type::PairList<String, Value>;
using Fields = oatpp::data::type::PairList<String, Value>;
template <class Value>
using UnorderedFields = oatpp::data::mapping::type::UnorderedMap<String, Value>;
using UnorderedFields = oatpp::data::type::UnorderedMap<String, Value>;
private:
static const mapping::type::Type* getParentType();
static const type::Type* getParentType();
static const char* Z__CLASS_TYPE_NAME();
static data::mapping::type::BaseObject::Properties* Z__CLASS_GET_FIELDS_MAP();
static data::type::BaseObject::Properties* Z__CLASS_GET_FIELDS_MAP();
static BaseObject::Properties* Z__CLASS_EXTEND(BaseObject::Properties* properties, BaseObject::Properties* extensionProperties);
public:
@ -483,14 +484,14 @@ public:
};
}}}}
}}}
namespace std {
template<class T>
struct hash<oatpp::data::mapping::type::DTOWrapper<T>> {
struct hash<oatpp::data::type::DTOWrapper<T>> {
typedef oatpp::data::mapping::type::DTOWrapper<T> argument_type;
typedef oatpp::data::type::DTOWrapper<T> argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const &ow) const noexcept {

View File

@ -24,10 +24,10 @@
#include "PairList.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId AbstractPairList::CLASS_ID("PairList");
}
}}}}
}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_PairList_hpp
#define oatpp_data_mapping_type_PairList_hpp
#ifndef oatpp_data_type_PairList_hpp
#define oatpp_data_type_PairList_hpp
#include "./Map.hpp"
#include "./Type.hpp"
@ -32,7 +32,7 @@
#include <initializer_list>
#include <utility>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -150,6 +150,6 @@ public:
}
}}}}
}}}
#endif // oatpp_data_mapping_type_PairList_hpp
#endif // oatpp_data_type_PairList_hpp

View File

@ -30,10 +30,10 @@
#include <fstream>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
String::String(const std::shared_ptr<std::string>& ptr, const type::Type* const valueType)
: oatpp::data::mapping::type::ObjectWrapper<std::string, __class::String>(ptr)
: oatpp::data::type::ObjectWrapper<std::string, __class::String>(ptr)
{
if(type::__class::String::getType() != valueType) {
throw std::runtime_error("Value type does not match");
@ -43,7 +43,7 @@ String::String(const std::shared_ptr<std::string>& ptr, const type::Type* const
String String::loadFromFile(const char* filename) {
std::ifstream file (filename, std::ios::in|std::ios::binary|std::ios::ate);
if (file.is_open()) {
auto result = data::mapping::type::String(file.tellg());
auto result = data::type::String(file.tellg());
file.seekg(0, std::ios::beg);
file.read(const_cast<char*>(result->data()), static_cast<std::streamsize>(result->size()));
file.close();
@ -186,4 +186,4 @@ namespace __class {
}
}
}}}}
}}}

View File

@ -33,7 +33,7 @@
#include <cctype>
#include <iterator>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -139,7 +139,7 @@ public:
operator std::string() const {
if (this->m_ptr == nullptr) {
throw std::runtime_error("[oatpp::data::mapping::type::String::operator std::string() const]: "
throw std::runtime_error("[oatpp::data::type::String::operator std::string() const]: "
"Error. Null pointer.");
}
return this->m_ptr.operator*();
@ -640,14 +640,14 @@ namespace __class {
}
}}}}
}}}
namespace std {
template<>
struct hash<oatpp::data::mapping::type::String> {
struct hash<oatpp::data::type::String> {
typedef oatpp::data::mapping::type::String argument_type;
typedef oatpp::data::type::String argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& s) const noexcept {
@ -658,9 +658,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Boolean> {
struct hash<oatpp::data::type::Boolean> {
typedef oatpp::data::mapping::type::Boolean argument_type;
typedef oatpp::data::type::Boolean argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -671,9 +671,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Int8> {
struct hash<oatpp::data::type::Int8> {
typedef oatpp::data::mapping::type::Int8 argument_type;
typedef oatpp::data::type::Int8 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -684,9 +684,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::UInt8> {
struct hash<oatpp::data::type::UInt8> {
typedef oatpp::data::mapping::type::UInt8 argument_type;
typedef oatpp::data::type::UInt8 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -697,9 +697,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Int16> {
struct hash<oatpp::data::type::Int16> {
typedef oatpp::data::mapping::type::Int16 argument_type;
typedef oatpp::data::type::Int16 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -710,9 +710,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::UInt16> {
struct hash<oatpp::data::type::UInt16> {
typedef oatpp::data::mapping::type::UInt16 argument_type;
typedef oatpp::data::type::UInt16 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -723,9 +723,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Int32> {
struct hash<oatpp::data::type::Int32> {
typedef oatpp::data::mapping::type::Int32 argument_type;
typedef oatpp::data::type::Int32 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -736,9 +736,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::UInt32> {
struct hash<oatpp::data::type::UInt32> {
typedef oatpp::data::mapping::type::UInt32 argument_type;
typedef oatpp::data::type::UInt32 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -749,9 +749,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Int64> {
struct hash<oatpp::data::type::Int64> {
typedef oatpp::data::mapping::type::Int64 argument_type;
typedef oatpp::data::type::Int64 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -762,9 +762,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::UInt64> {
struct hash<oatpp::data::type::UInt64> {
typedef oatpp::data::mapping::type::UInt64 argument_type;
typedef oatpp::data::type::UInt64 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -775,9 +775,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Float32> {
struct hash<oatpp::data::type::Float32> {
typedef oatpp::data::mapping::type::Float32 argument_type;
typedef oatpp::data::type::Float32 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -788,9 +788,9 @@ namespace std {
};
template<>
struct hash<oatpp::data::mapping::type::Float64> {
struct hash<oatpp::data::type::Float64> {
typedef oatpp::data::mapping::type::Float64 argument_type;
typedef oatpp::data::type::Float64 argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {

View File

@ -0,0 +1,141 @@
/***************************************************************************
*
* 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 "./Tree.hpp"
#include "oatpp/data/mapping/Tree.hpp"
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId Tree::CLASS_ID("Tree");
Type* Tree::getType() {
static Type type(CLASS_ID);
return &type;
}
}
Tree::Tree()
: ObjectWrapper<mapping::Tree, __class::Tree>()
{}
Tree::Tree(std::nullptr_t)
: ObjectWrapper<mapping::Tree, __class::Tree>()
{}
/**
* Copy constructor.
* @param other - other Any.
*/
Tree::Tree(const Tree& other)
: ObjectWrapper<mapping::Tree, __class::Tree>(other)
{}
/**
* Move constructor.
* @param other
*/
Tree::Tree(Tree&& other)
: ObjectWrapper<mapping::Tree, __class::Tree>(std::forward<ObjectWrapper<mapping::Tree, __class::Tree>>(other))
{}
Tree::Tree(const mapping::Tree& other)
: ObjectWrapper<mapping::Tree, __class::Tree>(std::make_shared<mapping::Tree>(other))
{}
Tree::Tree(mapping::Tree&& other)
: ObjectWrapper<mapping::Tree, __class::Tree>(std::make_shared<mapping::Tree>(std::forward<mapping::Tree>(other)))
{}
Tree::Tree(const std::shared_ptr<mapping::Tree>& node, const Type* const type)
: ObjectWrapper<mapping::Tree, __class::Tree>(node, type)
{}
Tree& Tree::operator = (std::nullptr_t) {
m_ptr.reset();
return *this;
}
Tree& Tree::operator = (const Tree& other) {
m_ptr = other.m_ptr;
return *this;
}
Tree& Tree::operator = (Tree&& other) {
m_ptr = std::move(other.m_ptr);
return *this;
}
Tree& Tree::operator = (const mapping::Tree& other) {
if(m_ptr) {
*m_ptr = other;
} else {
m_ptr = std::make_shared<mapping::Tree>(other);
}
return *this;
}
Tree& Tree::operator = (mapping::Tree&& other) {
if(m_ptr) {
*m_ptr = std::forward<mapping::Tree>(std::forward<mapping::Tree>(other));
} else {
m_ptr = std::make_shared<mapping::Tree>(std::forward<mapping::Tree>(other));
}
return *this;
}
bool Tree::operator == (std::nullptr_t) const {
return m_ptr.get() == nullptr;
}
bool Tree::operator != (std::nullptr_t) const {
return m_ptr.get() != nullptr;
}
bool Tree::operator == (const Tree& other) const {
return m_ptr.get() == other.m_ptr.get();
}
bool Tree::operator != (const Tree& other) const {
return !operator == (other);
}
const mapping::Tree& Tree::operator*() const {
if(!m_ptr) {
throw std::runtime_error("[oatpp::data::type::Tree::operator *()]: null-pointer exception");
}
return *m_ptr;
}
mapping::Tree& Tree::operator*() {
if(!m_ptr) {
throw std::runtime_error("[oatpp::data::type::Tree::operator *()]: null-pointer exception");
}
return *m_ptr;
}
}}}

View File

@ -0,0 +1,118 @@
/***************************************************************************
*
* 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_data_type_Tree_hpp
#define oatpp_data_type_Tree_hpp
#include "./Type.hpp"
namespace oatpp { namespace data { namespace mapping {
class Tree; // FWD
}}}
namespace oatpp { namespace data { namespace type {
namespace __class {
/**
* Tree class.
*/
class Tree {
public:
/**
* Class Id.
*/
static const ClassId CLASS_ID;
static Type *getType();
};
}
class Tree : public ObjectWrapper<mapping::Tree, __class::Tree> {
public:
/**
* Default constructor.
*/
Tree();
/**
* Nullptr constructor.
*/
Tree(std::nullptr_t);
/**
* Copy constructor.
* @param other - other Any.
*/
Tree(const Tree& other);
/**
* Move constructor.
* @param other
*/
Tree(Tree&& other);
/**
* Constructor from `mapping::Tree`.
* @param other
*/
Tree(const mapping::Tree& other);
/**
* Constructor.
* Construct from `mapping::Tree`
* @param other
*/
Tree(mapping::Tree&& other);
Tree(const std::shared_ptr<mapping::Tree>& node, const Type* const type);
Tree& operator = (std::nullptr_t);
Tree& operator = (const Tree& other);
Tree& operator = (Tree&& other);
Tree& operator = (const mapping::Tree& other);
Tree& operator = (mapping::Tree&& other);
bool operator == (std::nullptr_t) const;
bool operator != (std::nullptr_t) const;
bool operator == (const Tree& other) const;
bool operator != (const Tree& other) const;
const mapping::Tree& operator*() const;
mapping::Tree& operator*();
};
}}}
#endif //oatpp_data_type_Tree_hpp

View File

@ -24,7 +24,7 @@
#include "Type.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -106,4 +106,4 @@ bool Type::extends(const Type* other) const {
return false;
}
}}}}
}}}

View File

@ -33,7 +33,7 @@
#include <vector>
#include <string>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class Type; // FWD
@ -472,12 +472,12 @@ public:
const Type* parent = nullptr;
/**
* polymorphicDispatcher extends &id:oatpp::data::mapping::type::__class::Collection::PolymorphicDispatcher;.
* polymorphicDispatcher extends &id:oatpp::data::type::__class::Collection::PolymorphicDispatcher;.
*/
bool isCollection = false;
/**
* polymorphicDispatcher extends &id:oatpp::data::mapping::type::__class::Map::PolymorphicDispatcher;.
* polymorphicDispatcher extends &id:oatpp::data::type::__class::Map::PolymorphicDispatcher;.
*/
bool isMap = false;
};
@ -525,12 +525,12 @@ public:
const Type* const parent;
/**
* polymorphicDispatcher extends &id:oatpp::data::mapping::type::__class::Collection::PolymorphicDispatcher;.
* polymorphicDispatcher extends &id:oatpp::data::type::__class::Collection::PolymorphicDispatcher;.
*/
const bool isCollection;
/**
* polymorphicDispatcher extends &id:oatpp::data::mapping::type::__class::Map::PolymorphicDispatcher;.
* polymorphicDispatcher extends &id:oatpp::data::type::__class::Map::PolymorphicDispatcher;.
*/
const bool isMap;
@ -558,7 +558,7 @@ template<class Wrapper>
Wrapper ObjectWrapper<T, Clazz>::cast() const {
if(!Wrapper::Class::getType()->extends(m_valueType)) {
if(Wrapper::Class::getType() != __class::Void::getType() && m_valueType != __class::Void::getType()) {
throw std::runtime_error("[oatpp::data::mapping::type::ObjectWrapper::cast()]: Error. Invalid cast "
throw std::runtime_error("[oatpp::data::type::ObjectWrapper::cast()]: Error. Invalid cast "
"from '" + std::string(m_valueType->classId.name) + "' to '" +
std::string(Wrapper::Class::getType()->classId.name) + "'.");
}
@ -569,7 +569,7 @@ Wrapper ObjectWrapper<T, Clazz>::cast() const {
template <class T, class Clazz>
void ObjectWrapper<T, Clazz>::checkType(const Type* _this, const Type* other) {
if(!_this->extends(other)) {
throw std::runtime_error("[oatpp::data::mapping::type::ObjectWrapper::checkType()]: Error. "
throw std::runtime_error("[oatpp::data::type::ObjectWrapper::checkType()]: Error. "
"Type mismatch: stored '" + std::string(_this->classId.name) + "' vs "
"assigned '" + std::string(other->classId.name) + "'.");
}
@ -618,14 +618,14 @@ public: \
} \
}}}}
}}}
namespace std {
template<>
struct hash<oatpp::data::mapping::type::ClassId> {
struct hash<oatpp::data::type::ClassId> {
typedef oatpp::data::mapping::type::ClassId argument_type;
typedef oatpp::data::type::ClassId argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {
@ -635,9 +635,9 @@ struct hash<oatpp::data::mapping::type::ClassId> {
};
template<>
struct hash<oatpp::data::mapping::type::Void> {
struct hash<oatpp::data::type::Void> {
typedef oatpp::data::mapping::type::Void argument_type;
typedef oatpp::data::type::Void argument_type;
typedef v_uint64 result_type;
result_type operator()(argument_type const& v) const noexcept {

View File

@ -24,10 +24,10 @@
#include "UnorderedMap.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId AbstractUnorderedMap::CLASS_ID("UnorderedMap");
}
}}}}
}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_UnorderedMap_hpp
#define oatpp_data_mapping_type_UnorderedMap_hpp
#ifndef oatpp_data_type_UnorderedMap_hpp
#define oatpp_data_type_UnorderedMap_hpp
#include "./Map.hpp"
#include "./Type.hpp"
@ -32,7 +32,7 @@
#include <initializer_list>
#include <utility>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -123,6 +123,6 @@ namespace __class {
}
}}}}
}}}
#endif // oatpp_data_mapping_type_UnorderedMap_hpp
#endif // oatpp_data_type_UnorderedMap_hpp

View File

@ -24,10 +24,10 @@
#include "UnorderedSet.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId AbstractUnorderedSet::CLASS_ID("UnorderedSet");
}
}}}}
}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_UnorderedSet_hpp
#define oatpp_data_mapping_type_UnorderedSet_hpp
#ifndef oatpp_data_type_UnorderedSet_hpp
#define oatpp_data_type_UnorderedSet_hpp
#include "./Collection.hpp"
#include "./Type.hpp"
@ -31,7 +31,7 @@
#include <unordered_set>
#include <initializer_list>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -125,6 +125,6 @@ public:
}
}}}}
}}}
#endif // oatpp_data_mapping_type_UnorderedSet_hpp
#endif // oatpp_data_type_UnorderedSet_hpp

View File

@ -24,10 +24,10 @@
#include "Vector.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
const ClassId AbstractVector::CLASS_ID("Vector");
}
}}}}
}}}

View File

@ -22,8 +22,8 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_Vector_hpp
#define oatpp_data_mapping_type_Vector_hpp
#ifndef oatpp_data_type_Vector_hpp
#define oatpp_data_type_Vector_hpp
#include "./Collection.hpp"
#include "./Type.hpp"
@ -31,7 +31,7 @@
#include <vector>
#include <initializer_list>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace __class {
@ -121,6 +121,6 @@ namespace __class {
}
}}}}
}}}
#endif // oatpp_data_mapping_type_Vector_hpp
#endif // oatpp_data_type_Vector_hpp

View File

@ -24,505 +24,186 @@
#include "Deserializer.hpp"
#include "oatpp/data/stream/BufferStream.hpp"
#include "oatpp/utils/Conversion.hpp"
namespace oatpp { namespace json {
Deserializer::Deserializer(const std::shared_ptr<Config>& config)
: m_config(config)
{
m_methods.resize(static_cast<size_t>(data::mapping::type::ClassId::getClassCount()), nullptr);
setDeserializerMethod(data::mapping::type::__class::String::CLASS_ID, &Deserializer::deserializeString);
setDeserializerMethod(data::mapping::type::__class::Any::CLASS_ID, &Deserializer::deserializeAny);
setDeserializerMethod(data::mapping::type::__class::Int8::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int8>);
setDeserializerMethod(data::mapping::type::__class::UInt8::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt8>);
setDeserializerMethod(data::mapping::type::__class::Int16::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int16>);
setDeserializerMethod(data::mapping::type::__class::UInt16::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt16>);
setDeserializerMethod(data::mapping::type::__class::Int32::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int32>);
setDeserializerMethod(data::mapping::type::__class::UInt32::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt32>);
setDeserializerMethod(data::mapping::type::__class::Int64::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int64>);
setDeserializerMethod(data::mapping::type::__class::UInt64::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt64>);
setDeserializerMethod(data::mapping::type::__class::Float32::CLASS_ID, &Deserializer::deserializeFloat32);
setDeserializerMethod(data::mapping::type::__class::Float64::CLASS_ID, &Deserializer::deserializeFloat64);
setDeserializerMethod(data::mapping::type::__class::Boolean::CLASS_ID, &Deserializer::deserializeBoolean);
setDeserializerMethod(data::mapping::type::__class::AbstractObject::CLASS_ID, &Deserializer::deserializeObject);
setDeserializerMethod(data::mapping::type::__class::AbstractEnum::CLASS_ID, &Deserializer::deserializeEnum);
setDeserializerMethod(data::mapping::type::__class::AbstractVector::CLASS_ID, &Deserializer::deserializeCollection);
setDeserializerMethod(data::mapping::type::__class::AbstractList::CLASS_ID, &Deserializer::deserializeCollection);
setDeserializerMethod(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Deserializer::deserializeCollection);
setDeserializerMethod(data::mapping::type::__class::AbstractPairList::CLASS_ID, &Deserializer::deserializeMap);
setDeserializerMethod(data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Deserializer::deserializeMap);
}
void Deserializer::setDeserializerMethod(const data::mapping::type::ClassId& classId, DeserializerMethod method) {
const v_uint32 id = static_cast<v_uint32>(classId.id);
if(id >= m_methods.size()) {
m_methods.resize(id + 1, nullptr);
}
m_methods[id] = method;
}
void Deserializer::skipScope(oatpp::utils::parser::Caret& caret, v_char8 charOpen, v_char8 charClose){
const char* data = caret.getData();
v_buff_size size = caret.getDataSize();
v_buff_size pos = caret.getPosition();
v_int32 scopeCounter = 0;
bool isInString = false;
while(pos < size){
v_char8 a = static_cast<v_char8>(data[pos]);
if(a == charOpen){
if(!isInString){
scopeCounter ++;
}
} else if(a == charClose){
if(!isInString){
scopeCounter --;
if(scopeCounter == 0){
caret.setPosition(pos + 1);
return;
}
}
} else if(a == '"') {
isInString = !isInString;
} else if(a == '\\'){
pos ++;
}
pos ++;
void Deserializer::deserializeNull(State& state) {
if(state.caret->isAtText("null", true)){
state.tree->setNull();
} else {
state.errorStack.push("[oatpp::json::Deserializer::deserializeNull()]: 'null' expected");
}
}
void Deserializer::skipString(oatpp::utils::parser::Caret& caret){
const char* data = caret.getData();
v_buff_size size = caret.getDataSize();
v_buff_size pos = caret.getPosition();
v_int32 scopeCounter = 0;
while(pos < size){
v_char8 a = static_cast<v_char8>(data[pos]);
if(a == '"'){
scopeCounter ++;
if(scopeCounter == 2) {
caret.setPosition(pos + 1);
void Deserializer::deserializeNumber(State& state) {
if (!Utils::findDecimalSeparatorInCurrentNumber(*state.caret)) {
state.tree->setInteger(state.caret->parseInt());
} else {
state.tree->setFloat(state.caret->parseFloat64());
}
}
void Deserializer::deserializeBoolean(State& state) {
if(state.caret->isAtText("true", true)) {
state.tree->setValue<bool>(true);
} else if(state.caret->isAtText("false", true)) {
state.tree->setValue<bool>(false);
} else {
state.errorStack.push("[oatpp::json::Deserializer::deserializeBoolean()]: 'true' or 'false' expected");
}
}
void Deserializer::deserializeString(State& state) {
state.tree->setString(Utils::parseString(*state.caret));
}
void Deserializer::deserializeArray(State& state) {
if(state.caret->canContinueAtChar('[', 1)) {
state.tree->setVector(0);
auto& vector = state.tree->getVector();
state.caret->skipBlankChars();
v_int64 index = 0;
while(!state.caret->isAtChar(']') && state.caret->canContinue()){
state.caret->skipBlankChars();
vector.emplace_back();
State nestedState;
nestedState.caret = state.caret;
nestedState.config = state.config;
nestedState.tree = &vector[vector.size() - 1];
deserialize(nestedState);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::json::Deserializer::deserializeArray()]: index=" + utils::Conversion::int64ToStr(index));
return;
}
} else if(a == '\\'){
pos ++;
}
pos ++;
}
}
void Deserializer::skipToken(oatpp::utils::parser::Caret& caret){
const char* data = caret.getData();
v_buff_size size = caret.getDataSize();
v_buff_size pos = caret.getPosition();
while(pos < size){
v_char8 a = static_cast<v_char8>(data[pos]);
if(a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\b' || a == '\f' ||
a == '}' || a == ',' || a == ']') {
caret.setPosition(pos);
state.caret->skipBlankChars();
state.caret->canContinueAtChar(',', 1);
index ++;
}
if(!state.caret->canContinueAtChar(']', 1)){
state.errorStack.push("[oatpp::json::Deserializer::deserializeArray()]: ']' expected");
return;
}
pos ++;
}
}
void Deserializer::skipValue(oatpp::utils::parser::Caret& caret){
if(caret.isAtChar('{')){
skipScope(caret, '{', '}');
} else if(caret.isAtChar('[')){
skipScope(caret, '[', ']');
} else if(caret.isAtChar('"')){
skipString(caret);
} else {
skipToken(caret);
}
}
oatpp::Void Deserializer::deserializeFloat32(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
(void) deserializer;
(void) type;
if(caret.isAtText("null", true)){
return oatpp::Void(Float32::Class::getType());
} else {
return Float32(caret.parseFloat32());
}
}
oatpp::Void Deserializer::deserializeFloat64(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
(void) deserializer;
(void) type;
if(caret.isAtText("null", true)){
return oatpp::Void(Float64::Class::getType());
} else {
return Float64(caret.parseFloat64());
state.errorStack.push("[oatpp::json::Deserializer::deserializeArray()]: '[' expected");
}
}
oatpp::Void Deserializer::deserializeBoolean(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
void Deserializer::deserializeMap(State& state) {
(void) deserializer;
(void) type;
if(state.caret->canContinueAtChar('{', 1)) {
state.caret->skipBlankChars();
state.tree->setMap({});
auto& map = state.tree->getMap();
while (!state.caret->isAtChar('}') && state.caret->canContinue()) {
state.caret->skipBlankChars();
auto key = Utils::parseString(*state.caret);
if(state.caret->hasError()){
state.errorStack.push("[oatpp::json::Deserializer::deserializeMap()]: Item key name expected");
return;
}
state.caret->skipBlankChars();
if(!state.caret->canContinueAtChar(':', 1)){
state.errorStack.push("[oatpp::json::Deserializer::deserializeMap()]: ':' expected");
return;
}
state.caret->skipBlankChars();
State nestedState;
nestedState.caret = state.caret;
nestedState.config = state.config;
nestedState.tree = &map[key];
deserialize(nestedState);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::json::Deserializer::deserializeMap()]: key='" + key + "'");
return;
}
state.caret->skipBlankChars();
state.caret->canContinueAtChar(',', 1);
if(caret.isAtText("null", true)){
return oatpp::Void(Boolean::Class::getType());
} else {
if(caret.isAtText("true", true)) {
return Boolean(true);
} else if(caret.isAtText("false", true)) {
return Boolean(false);
} else {
caret.setError("[oatpp::json::Deserializer::readBooleanValue()]: Error. 'true' or 'false' - expected.", ERROR_CODE_VALUE_BOOLEAN);
return oatpp::Void(Boolean::Class::getType());
}
}
}
if(!state.caret->canContinueAtChar('}', 1)){
state.errorStack.push("[oatpp::json::Deserializer::deserializeMap()]: '}' expected");
return;
}
oatpp::Void Deserializer::deserializeString(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
(void) deserializer;
(void) type;
if(caret.isAtText("null", true)){
return oatpp::Void(String::Class::getType());
} else {
return oatpp::Void(Utils::parseString(caret).getPtr(), String::Class::getType());
state.errorStack.push("[oatpp::json::Deserializer::deserializeMap()]: '{' expected");
}
}
const data::mapping::type::Type* Deserializer::guessNumberType(oatpp::utils::parser::Caret& caret) {
if (!Utils::findDecimalSeparatorInCurrentNumber(caret)) {
if (*caret.getCurrData() == '-') {
return Int64::Class::getType();
} else {
return UInt64::Class::getType();
}
}
return Float64::Class::getType();
}
void Deserializer::deserialize(State& state) {
const data::mapping::type::Type* Deserializer::guessType(oatpp::utils::parser::Caret& caret) {
{
utils::parser::Caret::StateSaveGuard stateGuard(caret);
v_char8 c = static_cast<v_char8>(*caret.getCurrData());
switch (c) {
case '"':
return String::Class::getType();
case '{':
return oatpp::Fields<Any>::Class::getType();
case '[':
return oatpp::List<Any>::Class::getType();
case 't':
if(caret.isAtText("true")) return Boolean::Class::getType();
break;
case 'f':
if(caret.isAtText("false")) return Boolean::Class::getType();
break;
default:
if (c == '-' || caret.isAtDigitChar()) {
return guessNumberType(caret);
}
}
}
caret.setError("[oatpp::json::Deserializer::guessType()]: Error. Can't guess type for oatpp::Any.");
return nullptr;
}
state.caret->skipBlankChars();
oatpp::Void Deserializer::deserializeAny(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
(void) type;
if(caret.isAtText("null", true)){
return oatpp::Void(Any::Class::getType());
} else {
const Type* const fieldType = guessType(caret);
if(fieldType != nullptr) {
auto fieldValue = deserializer->deserialize(caret, fieldType);
auto anyHandle = std::make_shared<data::mapping::type::AnyHandle>(fieldValue.getPtr(), fieldValue.getValueType());
return oatpp::Void(anyHandle, Any::Class::getType());
}
}
return oatpp::Void(Any::Class::getType());
}
oatpp::Void Deserializer::deserializeEnum(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
auto polymorphicDispatcher = static_cast<const data::mapping::type::__class::AbstractEnum::PolymorphicDispatcher*>(
type->polymorphicDispatcher
);
data::mapping::type::EnumInterpreterError e = data::mapping::type::EnumInterpreterError::OK;
const auto& value = deserializer->deserialize(caret, polymorphicDispatcher->getInterpretationType());
if(caret.hasError()) {
return nullptr;
}
const auto& result = polymorphicDispatcher->fromInterpretation(value, e);
if(e == data::mapping::type::EnumInterpreterError::OK) {
return result;
}
switch(e) {
case data::mapping::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
caret.setError("[oatpp::json::Deserializer::deserializeEnum()]: Error. Enum constraint violated - 'NotNull'.");
auto c = *state.caret->getCurrData();
switch (c) {
case 'n':
deserializeNull(state);
break;
case '{':
deserializeMap(state);
break;
case '[':
deserializeArray(state);
break;
case '"':
deserializeString(state);
break;
case 't':
case 'f':
deserializeBoolean(state);
break;
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
deserializeNumber(state);
break;
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:
default:
caret.setError("[oatpp::json::Deserializer::deserializeEnum()]: Error. Can't deserialize Enum.");
state.errorStack.push("[json]: Unknown character.");
break;
}
return nullptr;
}
oatpp::Void Deserializer::deserializeCollection(Deserializer* deserializer, utils::parser::Caret& caret, const Type* type) {
if(caret.isAtText("null", true)){
return oatpp::Void(type);
}
if(caret.canContinueAtChar('[', 1)) {
auto dispatcher = static_cast<const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto collection = dispatcher->createObject();
auto itemType = dispatcher->getItemType();
caret.skipBlankChars();
while(!caret.isAtChar(']') && caret.canContinue()){
caret.skipBlankChars();
auto item = deserializer->deserialize(caret, itemType);
if(caret.hasError()){
return nullptr;
}
dispatcher->addItem(collection, item);
caret.skipBlankChars();
caret.canContinueAtChar(',', 1);
}
if(!caret.canContinueAtChar(']', 1)){
if(!caret.hasError()){
caret.setError("[oatpp::json::Deserializer::deserializeCollection()]: Error. ']' - expected", ERROR_CODE_ARRAY_SCOPE_CLOSE);
}
return nullptr;
}
return collection;
} else {
caret.setError("[oatpp::json::Deserializer::deserializeCollection()]: Error. '[' - expected", ERROR_CODE_ARRAY_SCOPE_OPEN);
return nullptr;
}
}
oatpp::Void Deserializer::deserializeMap(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
if(caret.isAtText("null", true)){
return oatpp::Void(type);
}
if(caret.canContinueAtChar('{', 1)) {
auto dispatcher = static_cast<const data::mapping::type::__class::Map::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto map = dispatcher->createObject();
auto keyType = dispatcher->getKeyType();
if(keyType->classId != oatpp::String::Class::CLASS_ID){
throw std::runtime_error("[oatpp::json::Deserializer::deserializeMap()]: Invalid json map key. Key should be String");
}
auto valueType = dispatcher->getValueType();
caret.skipBlankChars();
while (!caret.isAtChar('}') && caret.canContinue()) {
caret.skipBlankChars();
auto key = Utils::parseString(caret);
if(caret.hasError()){
return nullptr;
}
caret.skipBlankChars();
if(!caret.canContinueAtChar(':', 1)){
caret.setError("[oatpp::json::Deserializer::deserializeMap()]: Error. ':' - expected", ERROR_CODE_OBJECT_SCOPE_COLON_MISSING);
return nullptr;
}
caret.skipBlankChars();
auto item = deserializer->deserialize(caret, valueType);
if(caret.hasError()){
return nullptr;
}
dispatcher->addItem(map, key, item);
caret.skipBlankChars();
caret.canContinueAtChar(',', 1);
}
if(!caret.canContinueAtChar('}', 1)){
if(!caret.hasError()){
caret.setError("[oatpp::json::Deserializer::deserializeMap()]: Error. '}' - expected", ERROR_CODE_OBJECT_SCOPE_CLOSE);
}
return nullptr;
}
return map;
} else {
caret.setError("[oatpp::json::Deserializer::deserializeMap()]: Error. '{' - expected", ERROR_CODE_OBJECT_SCOPE_OPEN);
}
return nullptr;
}
oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type) {
if(caret.isAtText("null", true)){
return oatpp::Void(type);
}
if(caret.canContinueAtChar('{', 1)) {
auto dispatcher = static_cast<const oatpp::data::mapping::type::__class::AbstractObject::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto object = dispatcher->createObject();
const auto& fieldsMap = dispatcher->getProperties()->getMap();
caret.skipBlankChars();
std::vector<std::pair<oatpp::BaseObject::Property*, oatpp::String>> polymorphs;
while (!caret.isAtChar('}') && caret.canContinue()) {
caret.skipBlankChars();
auto key = Utils::parseStringToStdString(caret);
if(caret.hasError()){
return nullptr;
}
auto fieldIterator = fieldsMap.find(key);
if(fieldIterator != fieldsMap.end()){
caret.skipBlankChars();
if(!caret.canContinueAtChar(':', 1)){
caret.setError("[oatpp::json::Deserializer::readObject()]: Error. ':' - expected", ERROR_CODE_OBJECT_SCOPE_COLON_MISSING);
return nullptr;
}
caret.skipBlankChars();
auto field = fieldIterator->second;
if(field->info.typeSelector && field->type == oatpp::Any::Class::getType()) {
auto label = caret.putLabel();
skipValue(caret);
polymorphs.emplace_back(field, label.toString()); // store polymorphs for later processing.
} else {
auto value = deserializer->deserialize(caret, field->type);
if(field->info.required && value == nullptr) {
throw std::runtime_error("[oatpp::json::Deserializer::deserialize()]: "
"Error. " + std::string(type->nameQualifier) + "::"
+ std::string(field->name) + " is required!");
}
field->set(static_cast<oatpp::BaseObject *>(object.get()), value);
}
} else if (deserializer->getConfig()->allowUnknownFields) {
caret.skipBlankChars();
if(!caret.canContinueAtChar(':', 1)){
caret.setError("[oatpp::json::Deserializer::readObject()/if(config->allowUnknownFields){}]: Error. ':' - expected", ERROR_CODE_OBJECT_SCOPE_COLON_MISSING);
return nullptr;
}
caret.skipBlankChars();
skipValue(caret);
} else {
caret.setError("[oatpp::json::Deserializer::readObject()]: Error. Unknown field", ERROR_CODE_OBJECT_SCOPE_UNKNOWN_FIELD);
return nullptr;
}
caret.skipBlankChars();
caret.canContinueAtChar(',', 1);
}
if(!caret.canContinueAtChar('}', 1)){
if(!caret.hasError()){
caret.setError("[oatpp::json::Deserializer::readObject()]: Error. '}' - expected", ERROR_CODE_OBJECT_SCOPE_CLOSE);
}
return nullptr;
}
for(auto& p : polymorphs) {
utils::parser::Caret polyCaret(p.second);
auto selectedType = p.first->info.typeSelector->selectType(static_cast<oatpp::BaseObject *>(object.get()));
auto value = deserializer->deserialize(polyCaret, selectedType);
if(p.first->info.required && value == nullptr) {
throw std::runtime_error("[oatpp::json::Deserializer::deserialize()]: "
"Error. " + std::string(type->nameQualifier) + "::"
+ std::string(p.first->name) + " is required!");
}
oatpp::Any any(value);
p.first->set(static_cast<oatpp::BaseObject *>(object.get()), oatpp::Void(any.getPtr(), p.first->type));
}
return object;
} else {
caret.setError("[oatpp::json::Deserializer::readObject()]: Error. '{' - expected", ERROR_CODE_OBJECT_SCOPE_OPEN);
}
return nullptr;
}
oatpp::Void Deserializer::deserialize(utils::parser::Caret& caret, const Type* const type) {
auto id = static_cast<v_uint32>(type->classId.id);
auto& method = m_methods[id];
if(method) {
return (*method)(this, caret, type);
} else {
auto* interpretation = type->findInterpretation(m_config->enabledInterpretations);
if(interpretation) {
return interpretation->fromInterpretation(deserialize(caret, interpretation->getInterpretationType()));
}
throw std::runtime_error("[oatpp::json::Deserializer::deserialize()]: "
"Error. No deserialize method for type '" + std::string(type->classId.name) + "'");
}
}
const std::shared_ptr<Deserializer::Config>& Deserializer::getConfig() {
return m_config;
}
}}

View File

@ -26,6 +26,10 @@
#define oatpp_json_Deserializer_hpp
#include "./Utils.hpp"
#include "oatpp/data/mapping/ObjectMapper.hpp"
#include "oatpp/data/mapping/Tree.hpp"
#include "oatpp/utils/parser/Caret.hpp"
#include "oatpp/Types.hpp"
@ -38,50 +42,6 @@ namespace oatpp { namespace json {
* Deserialize oatpp DTO object from json. See [Data Transfer Object(DTO) component](https://oatpp.io/docs/components/dto/).
*/
class Deserializer {
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:
/**
* "'{' - expected"
*/
static constexpr v_int32 ERROR_CODE_OBJECT_SCOPE_OPEN = 1;
/**
* "'}' - expected"
*/
static constexpr v_int32 ERROR_CODE_OBJECT_SCOPE_CLOSE = 2;
/**
* "Unknown field"
*/
static constexpr v_int32 ERROR_CODE_OBJECT_SCOPE_UNKNOWN_FIELD = 3;
/**
* "':' - expected"
*/
static constexpr v_int32 ERROR_CODE_OBJECT_SCOPE_COLON_MISSING = 4;
/**
* "'[' - expected"
*/
static constexpr v_int32 ERROR_CODE_ARRAY_SCOPE_OPEN = 5;
/**
* "']' - expected"
*/
static constexpr v_int32 ERROR_CODE_ARRAY_SCOPE_CLOSE = 6;
/**
* "'true' or 'false' - expected"
*/
static constexpr v_int32 ERROR_CODE_VALUE_BOOLEAN = 7;
public:
/**
@ -89,123 +49,31 @@ public:
*/
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>();
}
/**
* Do not fail if unknown field is found in json.
* "unknown field" is the one which is not present in DTO object class.
*/
bool allowUnknownFields = true;
/**
* Enable type interpretations.
*/
std::vector<std::string> enabledInterpretations = {};
};
public:
typedef oatpp::Void (*DeserializerMethod)(Deserializer*, utils::parser::Caret&, const Type* const);
private:
static void skipScope(oatpp::utils::parser::Caret& caret, v_char8 charOpen, v_char8 charClose);
static void skipString(oatpp::utils::parser::Caret& caret);
static void skipToken(oatpp::utils::parser::Caret& caret);
static void skipValue(oatpp::utils::parser::Caret& caret);
private:
static const Type* guessNumberType(oatpp::utils::parser::Caret& caret);
static const Type* guessType(oatpp::utils::parser::Caret& caret);
private:
template<class T>
static oatpp::Void deserializeInt(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type){
(void) deserializer;
(void) type;
if(caret.isAtText("null", true)){
return oatpp::Void(T::Class::getType());
} else {
//TODO: shall we handle overflow cases like
// oatpp::String json = "128";
// auto value = jsonObjectMapper->readFromString<oatpp::Int8>(json); // UInt8 will overflow to -128
return T(static_cast<typename T::UnderlyingType>(caret.parseInt()));
}
}
template<class T>
static oatpp::Void deserializeUInt(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type){
(void) deserializer;
(void) type;
if(caret.isAtText("null", true)){
return oatpp::Void(T::Class::getType());
} else {
//TODO: shall we handle overflow cases like
// oatpp::String json = "256";
// auto value = jsonObjectMapper->readFromString<oatpp::UInt8>(json); // UInt8 will overflow to 0
return T(static_cast<typename T::UnderlyingType>(caret.parseUnsignedInt()));
}
}
static oatpp::Void deserializeFloat32(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeFloat64(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeBoolean(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeString(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeAny(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeEnum(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeCollection(Deserializer* deserializer, utils::parser::Caret& caret, const Type* type);
static oatpp::Void deserializeMap(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
static oatpp::Void deserializeObject(Deserializer* deserializer, utils::parser::Caret& caret, const Type* const type);
struct State {
const Config* config;
data::mapping::Tree* tree;
utils::parser::Caret* caret;
data::mapping::ErrorStack errorStack;
};
private:
std::shared_ptr<Config> m_config;
std::vector<DeserializerMethod> m_methods;
static void deserializeNull(State& state);
static void deserializeNumber(State& state);
static void deserializeBoolean(State& state);
static void deserializeString(State& state);
static void deserializeArray(State& state);
static void deserializeMap(State& state);
public:
/**
* Constructor.
* @param config
*/
Deserializer(const std::shared_ptr<Config>& config = std::make_shared<Config>());
/**
* Set deserializer method for type.
* @param classId - &id:oatpp::data::mapping::type::ClassId;.
* @param method - `typedef oatpp::Void (*DeserializerMethod)(Deserializer*, utils::parser::Caret&, const Type* const)`.
*/
void setDeserializerMethod(const data::mapping::type::ClassId& classId, DeserializerMethod method);
/**
* Deserialize text.
* @param caret - &id:oatpp::utils::parser::Caret;.
* @param type - &id:oatpp::data::mapping::type::Type;
* @return - `oatpp::Void` over deserialized object.
*/
oatpp::Void deserialize(utils::parser::Caret& caret, const Type* const type);
/**
* Get deserializer config.
* @return
*/
const std::shared_ptr<Config>& getConfig();
static void deserialize(State& state);
};

View File

@ -26,47 +26,97 @@
namespace oatpp { namespace json {
ObjectMapper::ObjectMapper(const std::shared_ptr<Serializer::Config>& serializerConfig,
const std::shared_ptr<Deserializer::Config>& deserializerConfig)
ObjectMapper::ObjectMapper(const SerializerConfig& serializerConfig, const DeserializerConfig& deserializerConfig)
: data::mapping::ObjectMapper(getMapperInfo())
, m_serializer(std::make_shared<Serializer>(serializerConfig))
, m_deserializer(std::make_shared<Deserializer>(deserializerConfig))
, m_serializerConfig(serializerConfig)
, m_deserializerConfig(deserializerConfig)
{}
ObjectMapper::ObjectMapper(const std::shared_ptr<Serializer>& serializer,
const std::shared_ptr<Deserializer>& deserializer)
: data::mapping::ObjectMapper(getMapperInfo())
, m_serializer(serializer)
, m_deserializer(deserializer)
{}
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);
void ObjectMapper::writeTree(data::stream::ConsistentOutputStream* stream, const data::mapping::Tree& tree, data::mapping::ErrorStack& errorStack) const {
Serializer::State state;
state.config = &m_serializerConfig.json;
state.tree = &tree;
Serializer::serializeToStream(stream, state);
if(!state.errorStack.empty()) {
errorStack = std::move(state.errorStack);
return;
}
}
std::shared_ptr<ObjectMapper> ObjectMapper::createShared(const std::shared_ptr<Serializer>& serializer,
const std::shared_ptr<Deserializer>& deserializer)
{
return std::make_shared<ObjectMapper>(serializer, deserializer);
void ObjectMapper::write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant, data::mapping::ErrorStack& errorStack) const {
/* if variant is Tree - we can serialize it right away */
if(variant.getValueType() == oatpp::Tree::Class::getType()) {
auto tree = static_cast<const data::mapping::Tree*>(variant.get());
writeTree(stream, *tree, errorStack);
return;
}
data::mapping::Tree tree;
data::mapping::ObjectToTreeMapper::State state;
state.config = &m_serializerConfig.mapper;
state.tree = &tree;
m_objectToTreeMapper.map(state, variant);
if(!state.errorStack.empty()) {
errorStack = std::move(state.errorStack);
return;
}
writeTree(stream, tree, errorStack);
}
void ObjectMapper::write(data::stream::ConsistentOutputStream* stream,
const oatpp::Void& variant) const {
m_serializer->serializeToStream(stream, variant);
oatpp::Void ObjectMapper::read(utils::parser::Caret& caret, const data::type::Type* type, data::mapping::ErrorStack& errorStack) const {
data::mapping::Tree tree;
{
Deserializer::State state;
state.caret = &caret;
state.tree = &tree;
state.config = &m_deserializerConfig.json;
Deserializer::deserialize(state);
if(!state.errorStack.empty()) {
errorStack = std::move(state.errorStack);
return nullptr;
}
}
/* if expected type is Tree (root element is Tree) - then we can just move deserialized tree */
if(type == data::type::Tree::Class::getType()) {
return oatpp::Tree(tree);
}
{
data::mapping::TreeToObjectMapper::State state;
state.tree = &tree;
state.config = &m_deserializerConfig.mapper;
const auto & result = m_treeToObjectMapper.map(state, type);
if(!state.errorStack.empty()) {
errorStack = std::move(state.errorStack);
return nullptr;
}
return result;
}
}
oatpp::Void ObjectMapper::read(oatpp::utils::parser::Caret& caret, const oatpp::data::mapping::type::Type* const type) const {
return m_deserializer->deserialize(caret, type);
const ObjectMapper::SerializerConfig& ObjectMapper::serializerConfig() const {
return m_serializerConfig;
}
std::shared_ptr<Serializer> ObjectMapper::getSerializer() {
return m_serializer;
const ObjectMapper::DeserializerConfig& ObjectMapper::deserializerConfig() const {
return m_deserializerConfig;
}
std::shared_ptr<Deserializer> ObjectMapper::getDeserializer() {
return m_deserializer;
ObjectMapper::SerializerConfig& ObjectMapper::serializerConfig() {
return m_serializerConfig;
}
ObjectMapper::DeserializerConfig& ObjectMapper::deserializerConfig() {
return m_deserializerConfig;
}
}}

View File

@ -28,6 +28,8 @@
#include "./Serializer.hpp"
#include "./Deserializer.hpp"
#include "oatpp/data/mapping/ObjectToTreeMapper.hpp"
#include "oatpp/data/mapping/TreeToObjectMapper.hpp"
#include "oatpp/data/mapping/ObjectMapper.hpp"
namespace oatpp { namespace json {
@ -43,74 +45,44 @@ private:
static Info info("application/json");
return info;
}
public:
class DeserializerConfig {
public:
data::mapping::TreeToObjectMapper::Config mapper;
Deserializer::Config json;
};
public:
class SerializerConfig {
public:
data::mapping::ObjectToTreeMapper::Config mapper;
Serializer::Config json;
};
private:
std::shared_ptr<Serializer> m_serializer;
std::shared_ptr<Deserializer> m_deserializer;
public:
/**
* Constructor.
* @param serializerConfig - &id:oatpp::json::Serializer::Config;.
* @param deserializerConfig - &id:oatpp::json::Deserializer::Config;.
*/
ObjectMapper(const std::shared_ptr<Serializer::Config>& serializerConfig,
const std::shared_ptr<Deserializer::Config>& deserializerConfig);
/**
* Constructor.
* @param serializer
* @param deserializer
*/
ObjectMapper(const std::shared_ptr<Serializer>& serializer = std::make_shared<Serializer>(),
const std::shared_ptr<Deserializer>& deserializer = std::make_shared<Deserializer>());
void writeTree(data::stream::ConsistentOutputStream* stream, const data::mapping::Tree& tree, data::mapping::ErrorStack& errorStack) const;
private:
SerializerConfig m_serializerConfig;
DeserializerConfig m_deserializerConfig;
private:
data::mapping::ObjectToTreeMapper m_objectToTreeMapper;
data::mapping::TreeToObjectMapper m_treeToObjectMapper;
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<ObjectMapper>
createShared(const std::shared_ptr<Serializer::Config>& serializerConfig,
const std::shared_ptr<Deserializer::Config>& deserializerConfig);
ObjectMapper(const SerializerConfig& serializerConfig = {}, const DeserializerConfig& deserializerConfig = {});
/**
* Create shared ObjectMapper.
* @param serializer
* @param deserializer
* @return
*/
static std::shared_ptr<ObjectMapper>
createShared(const std::shared_ptr<Serializer>& serializer = std::make_shared<Serializer>(),
const std::shared_ptr<Deserializer>& deserializer = std::make_shared<Deserializer>());
void write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant, data::mapping::ErrorStack& errorStack) const override;
/**
* Implementation of &id:oatpp::data::mapping::ObjectMapper::write;.
* @param stream - stream to write serializerd data to &id:oatpp::data::stream::ConsistentOutputStream;.
* @param variant - object to serialize &id:oatpp::Void;.
*/
void write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant) const override;
oatpp::Void read(oatpp::utils::parser::Caret& caret, const oatpp::Type* type, data::mapping::ErrorStack& errorStack) const override;
/**
* Implementation of &id:oatpp::data::mapping::ObjectMapper::read;.
* @param caret - &id:oatpp::utils::parser::Caret;.
* @param type - type of resultant object &id:oatpp::data::mapping::type::Type;.
* @return - &id:oatpp::Void; holding resultant object.
*/
oatpp::Void read(oatpp::utils::parser::Caret& caret, const oatpp::data::mapping::type::Type* const type) const override;
const SerializerConfig& serializerConfig() const;
const DeserializerConfig& deserializerConfig() const;
/**
* Get serializer.
* @return
*/
std::shared_ptr<Serializer> getSerializer();
/**
* Get deserializer.
* @return
*/
std::shared_ptr<Deserializer> getDeserializer();
SerializerConfig& serializerConfig();
DeserializerConfig& deserializerConfig();
};

View File

@ -25,55 +25,11 @@
#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>& config)
: m_config(config)
{
m_methods.resize(static_cast<size_t>(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<oatpp::Int8>);
setSerializerMethod(data::mapping::type::__class::UInt8::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt8>);
setSerializerMethod(data::mapping::type::__class::Int16::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int16>);
setSerializerMethod(data::mapping::type::__class::UInt16::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt16>);
setSerializerMethod(data::mapping::type::__class::Int32::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int32>);
setSerializerMethod(data::mapping::type::__class::UInt32::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt32>);
setSerializerMethod(data::mapping::type::__class::Int64::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int64>);
setSerializerMethod(data::mapping::type::__class::UInt64::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt64>);
setSerializerMethod(data::mapping::type::__class::Float32::CLASS_ID, &Serializer::serializePrimitive<oatpp::Float32>);
setSerializerMethod(data::mapping::type::__class::Float64::CLASS_ID, &Serializer::serializePrimitive<oatpp::Float64>);
setSerializerMethod(data::mapping::type::__class::Boolean::CLASS_ID, &Serializer::serializePrimitive<oatpp::Boolean>);
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<v_uint32>(classId.id);
if(id >= m_methods.size()) {
m_methods.resize(id + 1, nullptr);
}
m_methods[id] = method;
}
void Serializer::serializeString(data::stream::ConsistentOutputStream* stream, const char* data, v_buff_size size, v_uint32 escapeFlags) {
auto encodedValue = Utils::escapeString(data, size, escapeFlags);
stream->writeCharSimple('\"');
@ -81,222 +37,191 @@ 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(State& state) {
state.stream->writeSimple("null");
}
void Serializer::serializeString(State& state) {
const auto& str = state.tree->getString();
serializeString(state.stream, str->data(), static_cast<v_buff_size>(str->size()), state.config->escapeFlags);
}
void Serializer::serializeArray(State& state) {
state.stream->writeCharSimple('[');
State 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(nestedState.errorStack);
state.errorStack.push("[oatpp::json::Serializer::serializeArray()]: index=" + utils::Conversion::int64ToStr(index));
return;
}
}
index ++;
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto str = static_cast<std::string*>(polymorph.get());
serializeString(stream, str->data(), static_cast<v_buff_size>(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(State& state) {
state.stream->writeCharSimple('{');
State 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<v_buff_size>(str->size()), state.config->escapeFlags);
state.stream->writeCharSimple(':');
serialize(nestedState);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[oatpp::json::Serializer::serializeMap()]: key='" + pair.first + "'");
return;
}
}
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
auto anyHandle = static_cast<data::mapping::type::AnyHandle*>(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<const data::mapping::type::__class::AbstractEnum::PolymorphicDispatcher*>(
polymorph.getValueType()->polymorphicDispatcher
);
void Serializer::serializePairs(State& state) {
data::mapping::type::EnumInterpreterError e = data::mapping::type::EnumInterpreterError::OK;
serializer->serialize(stream, polymorphicDispatcher->toInterpretation(polymorph, e));
state.stream->writeCharSimple('{');
State 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<v_buff_size>(str->size()), state.config->escapeFlags);
state.stream->writeCharSimple(':');
serialize(nestedState);
if(!nestedState.errorStack.empty()) {
state.errorStack.splice(nestedState.errorStack);
state.errorStack.push("[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(State& state) {
switch (state.tree->getType()) {
case data::mapping::Tree::Type::UNDEFINED:
state.errorStack.push("[oatpp::json::Serializer::serialize()]: "
"UNDEFINED tree node is NOT serializable. To fix: set node value.");
return;
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<bool>()); return;
case data::mapping::Tree::Type::INT_8: state.stream->writeAsString(state.tree->getValue<v_int8>()); return;
case data::mapping::Tree::Type::UINT_8: state.stream->writeAsString(state.tree->getValue<v_uint8>()); return;
case data::mapping::Tree::Type::INT_16: state.stream->writeAsString(state.tree->getValue<v_int16>()); return;
case data::mapping::Tree::Type::UINT_16: state.stream->writeAsString(state.tree->getValue<v_uint16>()); return;
case data::mapping::Tree::Type::INT_32: state.stream->writeAsString(state.tree->getValue<v_int32>()); return;
case data::mapping::Tree::Type::UINT_32: state.stream->writeAsString(state.tree->getValue<v_uint32>()); return;
case data::mapping::Tree::Type::INT_64: state.stream->writeAsString(state.tree->getValue<v_int64>()); return;
case data::mapping::Tree::Type::UINT_64: state.stream->writeAsString(state.tree->getValue<v_uint64>()); return;
case data::mapping::Tree::Type::FLOAT_32: state.stream->writeAsString(state.tree->getValue<v_float32>()); return;
case data::mapping::Tree::Type::FLOAT_64: state.stream->writeAsString(state.tree->getValue<v_float64>()); 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.push("[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, State& state) {
if(!polymorph) {
stream->writeSimple("null", 4);
return;
}
if(state.config->useBeautifier) {
auto dispatcher = static_cast<const data::mapping::type::__class::Collection::PolymorphicDispatcher*>(
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<const data::mapping::type::__class::Map::PolymorphicDispatcher*>(
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<std::string>(untypedKey.getPtr()));
serializeString(stream, key->data(), static_cast<v_buff_size>(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<const oatpp::data::mapping::type::__class::AbstractObject::PolymorphicDispatcher*>(
type->polymorphicDispatcher
);
auto fields = dispatcher->getProperties()->getList();
auto object = static_cast<oatpp::BaseObject*>(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<oatpp::Any>();
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<v_buff_size>(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<v_uint32>(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::Config>& Serializer::getConfig() {
return m_config;
State 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);
}
}
}}

View File

@ -27,8 +27,10 @@
#include "./Utils.hpp"
#include "./Beautifier.hpp"
#include "oatpp/data/mapping/ObjectMapper.hpp"
#include "oatpp/data/mapping/Tree.hpp"
#include "oatpp/Types.hpp"
#include <vector>
namespace oatpp { namespace json {
@ -38,55 +40,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<Config> createShared(){
return std::make_shared<Config>();
}
/**
* 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 `"<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;
bool includeNullElements = true;
/**
* Use JSON Beautifier.
@ -103,97 +68,44 @@ public:
*/
oatpp::String beautifierNewLine = "\n";
/**
* Enable type interpretations.
*/
std::vector<std::string> enabledInterpretations = {};
/**
* Escape flags.
*/
v_uint32 escapeFlags = json::Utils::FLAG_ESCAPE_ALL;
};
public:
typedef void (*SerializerMethod)(Serializer*,
data::stream::ConsistentOutputStream*,
const oatpp::Void&);
struct State {
const Config* config;
const data::mapping::Tree* tree;
data::stream::ConsistentOutputStream* stream;
data::mapping::ErrorStack errorStack;
};
private:
template<class T>
static void serializePrimitive(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const oatpp::Void& polymorph){
(void) serializer;
if(polymorph){
stream->writeAsString(* static_cast<typename T::ObjectType*>(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(State& state);
static void serializeString(State& state);
static void serializeArray(State& state);
static void serializeMap(State& state);
static void serializePairs(State& state);
static void serializeAny(Serializer* serializer,
data::stream::ConsistentOutputStream* stream,
const oatpp::Void& polymorph);
static void serialize(State& 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<Config> m_config;
std::vector<SerializerMethod> m_methods;
public:
/**
* Constructor.
* @param config - serializer config.
*/
Serializer(const std::shared_ptr<Config>& config = std::make_shared<Config>());
/**
* 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<Config>& getConfig();
static void serializeToStream(data::stream::ConsistentOutputStream* stream, State& state);
};

View File

@ -29,7 +29,7 @@
#include "QueryResult.hpp"
#include "oatpp/data/mapping/TypeResolver.hpp"
#include "oatpp/data/mapping/type/Type.hpp"
#include "oatpp/data/type/Type.hpp"
#include "oatpp/data/share/MemoryLabel.hpp"
#include "oatpp/data/share/StringTemplate.hpp"

View File

@ -25,7 +25,7 @@
#ifndef oatpp_utils_Conversion_hpp
#define oatpp_utils_Conversion_hpp
#include "oatpp/data/mapping/type/Primitive.hpp"
#include "oatpp/data/type/Primitive.hpp"
#include "oatpp/Types.hpp"

View File

@ -63,67 +63,67 @@ public:
public:
/**
* Convenience typedef for &id:oatpp::data::mapping::type::String;.
* Convenience typedef for &id:oatpp::data::type::String;.
*/
typedef oatpp::String String;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int8;.
* Convenience typedef for &id:oatpp::data::type::Int8;.
*/
typedef oatpp::Int8 Int8;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt8;.
* Convenience typedef for &id:oatpp::data::type::UInt8;.
*/
typedef oatpp::UInt8 UInt8;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int16;.
* Convenience typedef for &id:oatpp::data::type::Int16;.
*/
typedef oatpp::Int16 Int16;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt16;.
* Convenience typedef for &id:oatpp::data::type::UInt16;.
*/
typedef oatpp::UInt16 UInt16;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int32;.
* Convenience typedef for &id:oatpp::data::type::Int32;.
*/
typedef oatpp::Int32 Int32;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt32;.
* Convenience typedef for &id:oatpp::data::type::UInt32;.
*/
typedef oatpp::UInt32 UInt32;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int64;.
* Convenience typedef for &id:oatpp::data::type::Int64;.
*/
typedef oatpp::Int64 Int64;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt64;.
* Convenience typedef for &id:oatpp::data::type::UInt64;.
*/
typedef oatpp::UInt64 UInt64;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Float32;.
* Convenience typedef for &id:oatpp::data::type::Float32;.
*/
typedef oatpp::Float32 Float32;
/**
* Convenience typedef for &id:atpp::data::mapping::type::Float64;.
* Convenience typedef for &id:atpp::data::type::Float64;.
*/
typedef oatpp::Float64 Float64;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Boolean;.
* Convenience typedef for &id:oatpp::data::type::Boolean;.
*/
typedef oatpp::Boolean Boolean;
template <class T>
using Enum = oatpp::data::mapping::type::Enum<T>;
using Enum = oatpp::data::type::Enum<T>;
template <class T>
using Object = oatpp::Object<T>;
@ -375,25 +375,25 @@ struct ApiClient::TypeInterpretation<oatpp::Boolean> {
};
template<class T, class I>
struct ApiClient::TypeInterpretation<data::mapping::type::EnumObjectWrapper<T, I>> {
struct ApiClient::TypeInterpretation<data::type::EnumObjectWrapper<T, I>> {
typedef data::mapping::type::EnumObjectWrapper<T, I> EnumOW;
typedef data::type::EnumObjectWrapper<T, I> EnumOW;
typedef typename I::UnderlyingTypeObjectWrapper UTOW;
static oatpp::String toString(const oatpp::String &typeName, const EnumOW &parameter) {
data::mapping::type::EnumInterpreterError error = data::mapping::type::EnumInterpreterError::OK;
data::type::EnumInterpreterError error = data::type::EnumInterpreterError::OK;
const auto& value = I::toInterpretation(parameter, error);
switch(error){
case data::mapping::type::EnumInterpreterError::OK: break;
case data::mapping::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
case data::type::EnumInterpreterError::OK: break;
case data::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
throw std::runtime_error(
"[oatpp::web::client::ApiClient::TypeInterpretation::toString()]: Error. Enum constraint violation - NotNull."
);
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:
case data::type::EnumInterpreterError::TYPE_MISMATCH_ENUM:
case data::type::EnumInterpreterError::TYPE_MISMATCH_ENUM_VALUE:
case data::type::EnumInterpreterError::ENTRY_NOT_FOUND:
default:
throw std::runtime_error(
"[oatpp::web::client::ApiClient::TypeInterpretation::toString()]: Error. Can't interpret Enum."

View File

@ -28,7 +28,7 @@
#include "./Response.hpp"
#include "oatpp/data/mapping/ObjectMapper.hpp"
#include "oatpp/data/mapping/type/Type.hpp"
#include "oatpp/data/type/Type.hpp"
namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing {

View File

@ -108,62 +108,62 @@ public:
typedef oatpp::data::mapping::ObjectMapper ObjectMapper;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::String;.
* Convenience typedef for &id:oatpp::data::type::String;.
*/
typedef oatpp::String String;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int8;.
* Convenience typedef for &id:oatpp::data::type::Int8;.
*/
typedef oatpp::Int8 Int8;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt8;.
* Convenience typedef for &id:oatpp::data::type::UInt8;.
*/
typedef oatpp::UInt8 UInt8;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int16;.
* Convenience typedef for &id:oatpp::data::type::Int16;.
*/
typedef oatpp::Int16 Int16;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt16;.
* Convenience typedef for &id:oatpp::data::type::UInt16;.
*/
typedef oatpp::UInt16 UInt16;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int32;.
* Convenience typedef for &id:oatpp::data::type::Int32;.
*/
typedef oatpp::Int32 Int32;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt32;.
* Convenience typedef for &id:oatpp::data::type::UInt32;.
*/
typedef oatpp::UInt32 UInt32;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Int64;.
* Convenience typedef for &id:oatpp::data::type::Int64;.
*/
typedef oatpp::Int64 Int64;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::UInt64;.
* Convenience typedef for &id:oatpp::data::type::UInt64;.
*/
typedef oatpp::UInt64 UInt64;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Float32;.
* Convenience typedef for &id:oatpp::data::type::Float32;.
*/
typedef oatpp::Float32 Float32;
/**
* Convenience typedef for &id:atpp::data::mapping::type::Float64;.
* Convenience typedef for &id:atpp::data::type::Float64;.
*/
typedef oatpp::Float64 Float64;
/**
* Convenience typedef for &id:oatpp::data::mapping::type::Boolean;.
* Convenience typedef for &id:oatpp::data::type::Boolean;.
*/
typedef oatpp::Boolean Boolean;
@ -182,7 +182,7 @@ public:
using Fields = oatpp::Fields<Value>;
template <class T>
using Enum = oatpp::data::mapping::type::Enum<T>;
using Enum = oatpp::data::type::Enum<T>;
protected:
@ -549,17 +549,17 @@ struct ApiController::TypeInterpretation <oatpp::Boolean> {
};
template<class T, class I>
struct ApiController::TypeInterpretation <data::mapping::type::EnumObjectWrapper<T, I>> {
struct ApiController::TypeInterpretation <data::type::EnumObjectWrapper<T, I>> {
typedef data::mapping::type::EnumObjectWrapper<T, I> EnumOW;
typedef data::type::EnumObjectWrapper<T, I> EnumOW;
typedef typename I::UnderlyingTypeObjectWrapper UTOW;
static EnumOW fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
const auto& parsedValue = ApiController::TypeInterpretation<UTOW>::fromString(typeName, text, success);
if(success) {
data::mapping::type::EnumInterpreterError error = data::mapping::type::EnumInterpreterError::OK;
data::type::EnumInterpreterError error = data::type::EnumInterpreterError::OK;
const auto& result = I::fromInterpretation(parsedValue, error);
if(error == data::mapping::type::EnumInterpreterError::OK) {
if(error == data::type::EnumInterpreterError::OK) {
return result.template cast<EnumOW>();
}
success = false;

View File

@ -32,7 +32,7 @@ Endpoint::Info::Param::Param()
{}
Endpoint::Info::Param::Param(const oatpp::String& pName,
oatpp::data::mapping::type::Type* pType)
oatpp::data::type::Type* pType)
: name(pName)
, type(pType)
{}
@ -41,7 +41,7 @@ const std::list<oatpp::String>& Endpoint::Info::Params::getOrder() const {
return m_order;
}
Endpoint::Info::Param& Endpoint::Info::Params::add(const oatpp::String& aname, oatpp::data::mapping::type::Type* type) {
Endpoint::Info::Param& Endpoint::Info::Params::add(const oatpp::String& aname, oatpp::data::type::Type* type) {
m_order.push_back(aname);
Endpoint::Info::Param& param = operator [](aname);
param.name = aname;

View File

@ -58,10 +58,10 @@ public:
struct Param {
Param();
Param(const oatpp::String& pName, oatpp::data::mapping::type::Type* pType);
Param(const oatpp::String& pName, oatpp::data::type::Type* pType);
oatpp::String name;
oatpp::data::mapping::type::Type* type;
oatpp::data::type::Type* type;
oatpp::String description;
oatpp::Boolean required = true;
@ -92,7 +92,7 @@ public:
* @param name
* @return new or existing parameter
*/
Param& add(const oatpp::String& name, oatpp::data::mapping::type::Type* type);
Param& add(const oatpp::String& name, oatpp::data::type::Type* type);
/**
* Add parameter name to list order
@ -119,7 +119,7 @@ public:
*/
struct ContentHints {
oatpp::String contentType;
oatpp::data::mapping::type::Type* schema;
oatpp::data::type::Type* schema;
oatpp::String description;
std::list<std::pair<oatpp::String, oatpp::Any>> examples;

View File

@ -29,7 +29,7 @@
#include <oatpp/web/protocol/http/incoming/Request.hpp>
#include "oatpp/web/protocol/http/Http.hpp"
#include "oatpp/macro/codegen.hpp"
#include "oatpp/data/mapping/type/Type.hpp"
#include "oatpp/data/type/Type.hpp"
namespace oatpp { namespace web { namespace server { namespace handler {

View File

@ -8,34 +8,14 @@ add_executable(oatppAllTests
oatpp/base/CommandLineArgumentsTest.hpp
oatpp/data/buffer/ProcessorTest.cpp
oatpp/data/buffer/ProcessorTest.hpp
oatpp/data/mapping/ObjectToTreeMapperTest.cpp
oatpp/data/mapping/ObjectToTreeMapperTest.hpp
oatpp/data/mapping/TreeTest.cpp
oatpp/data/mapping/TreeTest.hpp
oatpp/data/mapping/TreeToObjectMapperTest.cpp
oatpp/data/mapping/TreeToObjectMapperTest.hpp
oatpp/data/mapping/TypeResolverTest.cpp
oatpp/data/mapping/TypeResolverTest.hpp
oatpp/data/mapping/type/AnyTest.cpp
oatpp/data/mapping/type/AnyTest.hpp
oatpp/data/mapping/type/EnumTest.cpp
oatpp/data/mapping/type/EnumTest.hpp
oatpp/data/mapping/type/InterpretationTest.cpp
oatpp/data/mapping/type/InterpretationTest.hpp
oatpp/data/mapping/type/ListTest.cpp
oatpp/data/mapping/type/ListTest.hpp
oatpp/data/mapping/type/ObjectTest.cpp
oatpp/data/mapping/type/ObjectTest.hpp
oatpp/data/mapping/type/ObjectWrapperTest.cpp
oatpp/data/mapping/type/ObjectWrapperTest.hpp
oatpp/data/mapping/type/PairListTest.cpp
oatpp/data/mapping/type/PairListTest.hpp
oatpp/data/mapping/type/PrimitiveTest.cpp
oatpp/data/mapping/type/PrimitiveTest.hpp
oatpp/data/mapping/type/StringTest.cpp
oatpp/data/mapping/type/StringTest.hpp
oatpp/data/mapping/type/TypeTest.cpp
oatpp/data/mapping/type/TypeTest.hpp
oatpp/data/mapping/type/UnorderedMapTest.cpp
oatpp/data/mapping/type/UnorderedMapTest.hpp
oatpp/data/mapping/type/UnorderedSetTest.cpp
oatpp/data/mapping/type/UnorderedSetTest.hpp
oatpp/data/mapping/type/VectorTest.cpp
oatpp/data/mapping/type/VectorTest.hpp
oatpp/data/resource/InMemoryDataTest.cpp
oatpp/data/resource/InMemoryDataTest.hpp
oatpp/data/share/LazyStringMapTest.cpp
@ -46,6 +26,32 @@ add_executable(oatppAllTests
oatpp/data/share/StringTemplateTest.hpp
oatpp/data/stream/BufferStreamTest.cpp
oatpp/data/stream/BufferStreamTest.hpp
oatpp/data/type/AnyTest.cpp
oatpp/data/type/AnyTest.hpp
oatpp/data/type/EnumTest.cpp
oatpp/data/type/EnumTest.hpp
oatpp/data/type/InterpretationTest.cpp
oatpp/data/type/InterpretationTest.hpp
oatpp/data/type/ListTest.cpp
oatpp/data/type/ListTest.hpp
oatpp/data/type/ObjectTest.cpp
oatpp/data/type/ObjectTest.hpp
oatpp/data/type/ObjectWrapperTest.cpp
oatpp/data/type/ObjectWrapperTest.hpp
oatpp/data/type/PairListTest.cpp
oatpp/data/type/PairListTest.hpp
oatpp/data/type/PrimitiveTest.cpp
oatpp/data/type/PrimitiveTest.hpp
oatpp/data/type/StringTest.cpp
oatpp/data/type/StringTest.hpp
oatpp/data/type/TypeTest.cpp
oatpp/data/type/TypeTest.hpp
oatpp/data/type/UnorderedMapTest.cpp
oatpp/data/type/UnorderedMapTest.hpp
oatpp/data/type/UnorderedSetTest.cpp
oatpp/data/type/UnorderedSetTest.hpp
oatpp/data/type/VectorTest.cpp
oatpp/data/type/VectorTest.hpp
oatpp/encoding/Base64Test.cpp
oatpp/encoding/Base64Test.hpp
oatpp/encoding/UnicodeTest.cpp

View File

@ -35,24 +35,29 @@
#include "oatpp/async/ConditionVariableTest.hpp"
#include "oatpp/async/LockTest.hpp"
#include "oatpp/data/mapping/type/UnorderedMapTest.hpp"
#include "oatpp/data/mapping/type/PairListTest.hpp"
#include "oatpp/data/mapping/type/VectorTest.hpp"
#include "oatpp/data/mapping/type/UnorderedSetTest.hpp"
#include "oatpp/data/mapping/type/ListTest.hpp"
#include "oatpp/data/mapping/type/ObjectTest.hpp"
#include "oatpp/data/mapping/type/StringTest.hpp"
#include "oatpp/data/mapping/type/PrimitiveTest.hpp"
#include "oatpp/data/mapping/type/ObjectWrapperTest.hpp"
#include "oatpp/data/mapping/type/TypeTest.hpp"
#include "oatpp/data/mapping/type/AnyTest.hpp"
#include "oatpp/data/mapping/type/EnumTest.hpp"
#include "oatpp/data/mapping/type/InterpretationTest.hpp"
#include "oatpp/data/type/UnorderedMapTest.hpp"
#include "oatpp/data/type/PairListTest.hpp"
#include "oatpp/data/type/VectorTest.hpp"
#include "oatpp/data/type/UnorderedSetTest.hpp"
#include "oatpp/data/type/ListTest.hpp"
#include "oatpp/data/type/ObjectTest.hpp"
#include "oatpp/data/type/StringTest.hpp"
#include "oatpp/data/type/PrimitiveTest.hpp"
#include "oatpp/data/type/ObjectWrapperTest.hpp"
#include "oatpp/data/type/TypeTest.hpp"
#include "oatpp/data/type/AnyTest.hpp"
#include "oatpp/data/type/EnumTest.hpp"
#include "oatpp/data/type/InterpretationTest.hpp"
#include "oatpp/data/mapping/TypeResolverTest.hpp"
#include "oatpp/data/resource/InMemoryDataTest.hpp"
#include "oatpp/data/stream/BufferStreamTest.hpp"
#include "oatpp/data/mapping/TreeTest.hpp"
#include "oatpp/data/mapping/ObjectToTreeMapperTest.hpp"
#include "oatpp/data/mapping/TreeToObjectMapperTest.hpp"
#include "oatpp/data/share/LazyStringMapTest.hpp"
#include "oatpp/data/share/StringTemplateTest.hpp"
#include "oatpp/data/share/MemoryLabelTest.hpp"
@ -64,6 +69,8 @@
#include "oatpp/async/Coroutine.hpp"
#include "oatpp/Types.hpp"
#include "oatpp/data/mapping/Tree.hpp"
#include "oatpp/Environment.hpp"
#include <iostream>
@ -73,14 +80,24 @@ namespace {
void runTests() {
oatpp::Environment::printCompilationConfig();
OATPP_LOGD("Tests", "oatpp::String size=%lu", sizeof(oatpp::String))
OATPP_LOGD("Tests", "std::string size=%lu", sizeof(std::string))
OATPP_LOGD("Tests", "Vector size=%lu", sizeof(std::vector<int>))
OATPP_LOGD("Tests", "Map size=%lu", sizeof(std::unordered_map<oatpp::String, oatpp::String>))
OATPP_LOGD("Tests", "Tree size=%lu", sizeof(oatpp::data::mapping::Tree))
//return;
OATPP_LOGD("Tests", "coroutine handle size=%lu", sizeof(oatpp::async::CoroutineHandle))
OATPP_LOGD("Tests", "coroutine size=%lu", sizeof(oatpp::async::AbstractCoroutine))
OATPP_LOGD("Tests", "action size=%lu", sizeof(oatpp::async::Action))
OATPP_LOGD("Tests", "class count=%d", oatpp::data::mapping::type::ClassId::getClassCount())
OATPP_LOGD("Tests", "class count=%d", oatpp::data::type::ClassId::getClassCount())
auto names = oatpp::data::mapping::type::ClassId::getRegisteredClassNames();
auto names = oatpp::data::type::ClassId::getRegisteredClassNames();
v_int32 i = 0;
for(auto& name : names) {
OATPP_LOGD("CLASS", "%d --> '%s'", i, name)
@ -95,26 +112,29 @@ void runTests() {
OATPP_RUN_TEST(oatpp::data::share::StringTemplateTest);
OATPP_RUN_TEST(oatpp::data::buffer::ProcessorTest);
OATPP_RUN_TEST(oatpp::data::stream::BufferStreamTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::ObjectWrapperTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::TypeTest);
OATPP_RUN_TEST(oatpp::data::mapping::TreeTest);
OATPP_RUN_TEST(oatpp::data::mapping::ObjectToTreeMapperTest);
OATPP_RUN_TEST(oatpp::data::mapping::TreeToObjectMapperTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::StringTest);
OATPP_RUN_TEST(oatpp::data::type::ObjectWrapperTest);
OATPP_RUN_TEST(oatpp::data::type::TypeTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::PrimitiveTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::ListTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::VectorTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::UnorderedSetTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::PairListTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::UnorderedMapTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::AnyTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::EnumTest);
OATPP_RUN_TEST(oatpp::data::type::StringTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::ObjectTest);
OATPP_RUN_TEST(oatpp::data::type::PrimitiveTest);
OATPP_RUN_TEST(oatpp::data::type::ListTest);
OATPP_RUN_TEST(oatpp::data::type::VectorTest);
OATPP_RUN_TEST(oatpp::data::type::UnorderedSetTest);
OATPP_RUN_TEST(oatpp::data::type::PairListTest);
OATPP_RUN_TEST(oatpp::data::type::UnorderedMapTest);
OATPP_RUN_TEST(oatpp::data::type::AnyTest);
OATPP_RUN_TEST(oatpp::data::type::EnumTest);
OATPP_RUN_TEST(oatpp::data::mapping::type::InterpretationTest);
OATPP_RUN_TEST(oatpp::data::type::ObjectTest);
OATPP_RUN_TEST(oatpp::data::type::InterpretationTest);
OATPP_RUN_TEST(oatpp::data::mapping::TypeResolverTest);
OATPP_RUN_TEST(oatpp::data::resource::InMemoryDataTest);
@ -133,9 +153,10 @@ void runTests() {
OATPP_RUN_TEST(oatpp::json::UnorderedSetTest);
OATPP_RUN_TEST(oatpp::json::DeserializerTest);
OATPP_RUN_TEST(oatpp::json::DTOMapperPerfTest);
OATPP_RUN_TEST(oatpp::json::DTOMapperTest);
OATPP_RUN_TEST(oatpp::json::DTOMapperPerfTest);
OATPP_RUN_TEST(oatpp::json::DTOMapperTest);
OATPP_RUN_TEST(oatpp::test::encoding::Base64Test);
OATPP_RUN_TEST(oatpp::test::encoding::UnicodeTest);
OATPP_RUN_TEST(oatpp::test::encoding::UrlTest);
@ -224,6 +245,8 @@ void runTests() {
}
}
}

View File

@ -0,0 +1,177 @@
/***************************************************************************
*
* 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 "ObjectToTreeMapperTest.hpp"
#include "oatpp/data/mapping/ObjectToTreeMapper.hpp"
#include "oatpp/macro/codegen.hpp"
#include <iostream>
namespace oatpp { namespace data { namespace mapping {
namespace {
#include OATPP_CODEGEN_BEGIN(DTO)
class TestDto1 : public oatpp::DTO {
DTO_INIT(TestDto1, DTO)
DTO_FIELD(String, str);
DTO_FIELD(Int8, i8);
DTO_FIELD(UInt8, ui8);
DTO_FIELD(Int16, i16);
DTO_FIELD(UInt16, ui16);
DTO_FIELD(Int32, i32);
DTO_FIELD(UInt32, ui32);
DTO_FIELD(Int64, i64);
DTO_FIELD(UInt64, ui64);
DTO_FIELD(Vector<oatpp::Object<TestDto1>>, vector);
DTO_FIELD(UnorderedFields<oatpp::Object<TestDto1>>, map);
DTO_FIELD(Fields<String>, pairs);
};
#include OATPP_CODEGEN_END(DTO)
}
void ObjectToTreeMapperTest::onRun() {
ObjectToTreeMapper mapper;
ObjectToTreeMapper::Config config;
{
OATPP_LOGD(TAG, "Map String")
Tree tree;
ObjectToTreeMapper::State state;
state.tree = &tree;
state.config = &config;
oatpp::String str = oatpp::String("Hello World");
mapper.map(state, str);
OATPP_ASSERT(state.errorStack.empty())
OATPP_ASSERT(tree.getType() == Tree::Type::STRING)
OATPP_ASSERT(tree.getString() == str)
OATPP_ASSERT(tree.getString().get() == str.get())
}
{
OATPP_LOGD(TAG, "Map String in Any")
Tree tree;
ObjectToTreeMapper::State state;
state.tree = &tree;
state.config = &config;
oatpp::String str = oatpp::String("Hello World");
oatpp::Any any = str;
mapper.map(state, any);
OATPP_ASSERT(state.errorStack.empty())
OATPP_ASSERT(tree.getType() == Tree::Type::STRING)
OATPP_ASSERT(tree.getString() == str)
OATPP_ASSERT(tree.getString().get() == str.get())
}
{
OATPP_LOGD(TAG, "Map Object")
Tree tree;
ObjectToTreeMapper::State state;
state.tree = &tree;
state.config = &config;
auto obj = TestDto1::createShared();
obj->str = "hello object";
obj->i8 = -8;
obj->ui8 = 8;
obj->i16 = -16;
obj->ui16 = 16;
obj->i32 = -32;
obj->ui32 = 32;
obj->i64 = -64;
obj->ui64 = 64;
obj->vector = {TestDto1::createShared(), TestDto1::createShared(), TestDto1::createShared()};
obj->map = {{"key1", TestDto1::createShared()}, {"key2", TestDto1::createShared()}, {"key3", TestDto1::createShared()}};
obj->pairs = {{"same-key", "value1"}, {"same-key", "value2"}, {"same-key", "value3"}};
obj->vector[0]->str = "vec-item-1";
obj->vector[1]->str = "vec-item-2";
obj->vector[2]->str = "vec-item-3";
obj->map["key1"]->i64 = 1;
obj->map["key2"]->i64 = 2;
obj->map["key3"]->i64 = 3;
mapper.map(state, obj);
OATPP_ASSERT(state.errorStack.empty())
std::cout << *tree.debugPrint() << std::endl;
OATPP_ASSERT(tree.getType() == Tree::Type::MAP)
OATPP_ASSERT(tree["str"].getString() == "hello object")
OATPP_ASSERT(tree["i8"].getValue<v_int8>() == -8)
OATPP_ASSERT(tree["ui8"].getValue<v_uint8>() == 8)
OATPP_ASSERT(tree["i16"].getValue<v_int16>() == -16)
OATPP_ASSERT(tree["ui16"].getValue<v_uint16>() == 16)
OATPP_ASSERT(tree["i32"].getValue<v_int32>() == -32)
OATPP_ASSERT(tree["ui32"].getValue<v_uint32>() == 32)
OATPP_ASSERT(tree["i64"].getValue<v_int64>() == -64)
OATPP_ASSERT(tree["ui64"].getValue<v_uint64>() == 64)
OATPP_ASSERT(tree["vector"].getVector().size() == 3)
OATPP_ASSERT(tree["vector"][0]["str"].getString() == "vec-item-1")
OATPP_ASSERT(tree["vector"][1]["str"].getString() == "vec-item-2")
OATPP_ASSERT(tree["vector"][2]["str"].getString() == "vec-item-3")
OATPP_ASSERT(tree["map"].getMap().size() == 3)
OATPP_ASSERT(tree["map"]["key1"]["i64"].getValue<v_int64>() == 1)
OATPP_ASSERT(tree["map"]["key2"]["i64"].getValue<v_int64>() == 2)
OATPP_ASSERT(tree["map"]["key3"]["i64"].getValue<v_int64>() == 3)
auto& pairs = tree["pairs"].getPairs();
OATPP_ASSERT(pairs.size() == 3)
OATPP_ASSERT(pairs[0].first == "same-key" && pairs[0].second.getString() == "value1")
OATPP_ASSERT(pairs[1].first == "same-key" && pairs[1].second.getString() == "value2")
OATPP_ASSERT(pairs[2].first == "same-key" && pairs[2].second.getString() == "value3")
}
}
}}}

View File

@ -0,0 +1,40 @@
/***************************************************************************
*
* 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_data_mapping_ObjectToTreeMapperTest_hpp
#define oatpp_data_mapping_ObjectToTreeMapperTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping {
class ObjectToTreeMapperTest : public oatpp::test::UnitTest {
public:
ObjectToTreeMapperTest() : UnitTest("TEST[oatpp::data::mapping::ObjectToTreeMapperTest]") {}
void onRun() override;
};
}}}
#endif /* oatpp_data_mapping_ObjectToTreeMapperTest_hpp */

View File

@ -0,0 +1,181 @@
/***************************************************************************
*
* 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 "TreeTest.hpp"
#include "oatpp/data/mapping/Tree.hpp"
#include "oatpp/utils/Conversion.hpp"
#include <limits>
namespace oatpp { namespace data { namespace mapping {
namespace {
template<typename T>
void testTreeValue(T value) {
Tree node;
//node.setValue<T>(value);
node = value;
auto v = node.getValue<T>();
OATPP_ASSERT(v == value && "value check")
node.setValue<T>(std::numeric_limits<T>::min());
auto min = node.getValue<T>();
OATPP_ASSERT(min == std::numeric_limits<T>::min() && "min check")
node.setValue<T>(std::numeric_limits<T>::max());
auto max = node.getValue<T>();
OATPP_ASSERT(max == std::numeric_limits<T>::max() && "max check")
}
}
void TreeTest::onRun() {
testTreeValue<bool>(true);
testTreeValue<v_int8>(16);
testTreeValue<v_uint8>(16);
testTreeValue<v_int16>(16);
testTreeValue<v_uint16>(16);
testTreeValue<v_int32>(16);
testTreeValue<v_uint32>(16);
testTreeValue<v_int64>(16);
testTreeValue<v_uint64>(16);
testTreeValue<v_float32>(16);
testTreeValue<v_float64>(16);
{
Tree node;
oatpp::String original = "Hello World!";
node.setString(original);
auto stored = node.getString();
OATPP_ASSERT(stored == original)
OATPP_ASSERT(stored.get() == original.get())
}
{
Tree node1;
Tree node2;
node1.setString("Hello World!");
node2 = node1;
OATPP_ASSERT(node1.getString() == "Hello World!")
OATPP_ASSERT(node1.getType() == Tree::Type::STRING)
OATPP_ASSERT(node2.getString() == "Hello World!")
OATPP_ASSERT(node2.getType() == Tree::Type::STRING)
}
{
Tree node1;
Tree node2;
node1.setString("Hello World!");
node2 = std::move(node1);
OATPP_ASSERT(node1.isNull())
OATPP_ASSERT(node2.getString() == "Hello World!")
OATPP_ASSERT(node2.getType() == Tree::Type::STRING)
}
{
std::vector<Tree> originalVector(10);
for(v_uint32 i = 0; i < 10; i ++) {
originalVector.at(i).setValue(i);
}
Tree node;
node.setVector(originalVector);
auto& vector = node.getVector();
OATPP_ASSERT(vector.size() == originalVector.size())
for(v_uint32 i = 0; i < originalVector.size(); i ++) {
OATPP_ASSERT(originalVector.at(i).getValue<v_uint32>() == vector.at(i).getValue<v_uint32>())
}
originalVector.resize(5);
OATPP_ASSERT(vector.size() == 10)
vector.at(0).setString("Hello");
OATPP_ASSERT(vector.at(0).getString() == "Hello")
OATPP_ASSERT(originalVector.at(0).getValue<v_uint32>() == 0)
}
{
TreeMap originalMap;
for(v_uint32 i = 0; i < 10; i ++) {
originalMap["node_" + utils::Conversion::int32ToStr(static_cast<v_int32>(i))].setValue(i);
}
Tree node;
node.setMap(originalMap);
auto& map = node.getMap();
OATPP_ASSERT(map.size() == originalMap.size())
for(v_uint32 i = 0; i < originalMap.size(); i ++) {
OATPP_ASSERT(originalMap[i].first == map[i].first)
OATPP_ASSERT(originalMap[i].second.get().getValue<v_uint32>() == map[i].second.get().getValue<v_uint32>())
}
originalMap[0].second.get().setValue<v_uint32>(100);
OATPP_ASSERT(map[0].second.get().getValue<v_uint32>() == 0)
OATPP_ASSERT(originalMap[0].second.get().getValue<v_uint32>() == 100)
}
{
Tree article;
oatpp::Tree ot;
article["name"] = "Hello World!";
article["pages"] = 96;
article["references"].setVector(2);
article["references"][0]["author"] = "Alexander";
article["references"][1]["author"] = "Leonid";
article["references"].getVector().size();
v_int32 value = article["pages"];
oatpp::String author = article["references"][0]["author"];
OATPP_LOGD(TAG, "pages=%d', refs='%s', node_type=%d", value, author->c_str(), static_cast<v_int32>(article.getType()))
}
}
}}}

View File

@ -0,0 +1,40 @@
/***************************************************************************
*
* 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_data_mapping_TreeTest_hpp
#define oatpp_data_mapping_TreeTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping {
class TreeTest : public oatpp::test::UnitTest {
public:
TreeTest() : UnitTest("TEST[oatpp::data::mapping::TreeTest]") {}
void onRun() override;
};
}}}
#endif /* oatpp_data_mapping_TreeTest_hpp */

View File

@ -0,0 +1,157 @@
/***************************************************************************
*
* 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 "TreeToObjectMapperTest.hpp"
#include "oatpp/json/ObjectMapper.hpp"
#include "oatpp/data/mapping/TreeToObjectMapper.hpp"
#include "oatpp/macro/codegen.hpp"
#include <iostream>
namespace oatpp { namespace data { namespace mapping {
namespace {
#include OATPP_CODEGEN_BEGIN(DTO)
class TestDto1 : public oatpp::DTO {
DTO_INIT(TestDto1, DTO)
DTO_FIELD(String, str);
DTO_FIELD(Int8, i8);
DTO_FIELD(UInt8, ui8);
DTO_FIELD(Int16, i16);
DTO_FIELD(UInt16, ui16);
DTO_FIELD(Int32, i32);
DTO_FIELD(UInt32, ui32);
DTO_FIELD(Int64, i64);
DTO_FIELD(UInt64, ui64);
DTO_FIELD(Vector<oatpp::Object<TestDto1>>, vector);
DTO_FIELD(UnorderedFields<oatpp::Object<TestDto1>>, map);
DTO_FIELD(Fields<String>, pairs);
};
#include OATPP_CODEGEN_END(DTO)
}
void TreeToObjectMapperTest::onRun() {
json::ObjectMapper jsonMapper;
jsonMapper.serializerConfig().json.useBeautifier = true;
jsonMapper.serializerConfig().mapper.includeNullFields = false;
TreeToObjectMapper mapper;
TreeToObjectMapper::Config config;
ObjectToTreeMapper reverseMapper;
ObjectToTreeMapper::Config reverseConfig;
{
Tree tree;
tree["str"] = "Hello World!";
tree["i8"] = -8;
tree["ui8"] = 8;
tree["i16"] = -16;
tree["ui16"] = 16;
tree["i32"] = -32;
tree["ui32"] = 32;
tree["i64"] = -64;
tree["ui64"] = 64;
tree["vector"].setVector(3);
tree["vector"][0]["str"] = "nested_1 (in vector)";
tree["vector"][1]["str"] = "nested_2 (in vector)";
tree["vector"][2]["str"] = "nested_3 (in vector)";
tree["map"]["nested_1"]["i32"] = 1;
tree["map"]["nested_2"]["i32"] = 2;
tree["map"]["nested_3"]["i32"] = 3;
auto& pairs = tree["pairs"].getPairs();
pairs.push_back({"same-key", {}});
pairs.push_back({"same-key", {}});
pairs.push_back({"same-key", {}});
pairs[0].second = "value1";
pairs[1].second = "value2";
pairs[2].second = "value3";
TreeToObjectMapper::State state;
state.config = &config;
state.tree = &tree;
const auto& polymorph = mapper.map(state,oatpp::Object<TestDto1>::Class::getType());
if(state.errorStack.empty()) {
auto json = jsonMapper.writeToString(polymorph);
std::cout << *json << std::endl;
} else {
auto err = state.errorStack.stacktrace();
std::cout << *err << std::endl;
}
auto obj = polymorph.cast<oatpp::Object<TestDto1>>();
OATPP_ASSERT(obj->str == "Hello World!")
OATPP_ASSERT(obj->i8 == -8)
OATPP_ASSERT(obj->ui8 == 8)
OATPP_ASSERT(obj->i16 == -16)
OATPP_ASSERT(obj->ui16 == 16)
OATPP_ASSERT(obj->i32 == -32)
OATPP_ASSERT(obj->ui32 == 32)
OATPP_ASSERT(obj->i64 == -64)
OATPP_ASSERT(obj->ui64 == 64)
OATPP_ASSERT(obj->vector->size() == 3)
OATPP_ASSERT(obj->vector[0]->str == "nested_1 (in vector)")
OATPP_ASSERT(obj->vector[1]->str == "nested_2 (in vector)")
OATPP_ASSERT(obj->vector[2]->str == "nested_3 (in vector)")
OATPP_ASSERT(obj->map->size() == 3)
OATPP_ASSERT(obj->map["nested_1"]->i32 = 1)
OATPP_ASSERT(obj->map["nested_2"]->i32 = 2)
OATPP_ASSERT(obj->map["nested_3"]->i32 = 3)
OATPP_ASSERT(obj->pairs->size() == 3)
OATPP_ASSERT(obj->pairs[0].first == "same-key" && obj->pairs[0].second == "value1")
OATPP_ASSERT(obj->pairs[1].first == "same-key" && obj->pairs[1].second == "value2")
OATPP_ASSERT(obj->pairs[2].first == "same-key" && obj->pairs[2].second == "value3")
}
}
}}}

View File

@ -0,0 +1,40 @@
/***************************************************************************
*
* 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_data_mapping_TreeToObjectMapperTest_hpp
#define oatpp_data_mapping_TreeToObjectMapperTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping {
class TreeToObjectMapperTest : public oatpp::test::UnitTest {
public:
TreeToObjectMapperTest() : UnitTest("TEST[oatpp::data::mapping::TreeToObjectMapperTest]") {}
void onRun() override;
};
}}}
#endif /* oatpp_data_mapping_TreeToObjectMapperTest_hpp */

View File

@ -32,7 +32,7 @@ namespace oatpp { namespace data { namespace mapping {
class TypeResolverTest : public oatpp::test::UnitTest{
public:
TypeResolverTest():UnitTest("TEST[data::mapping::type::TypeResolverTest]"){}
TypeResolverTest():UnitTest("TEST[data::type::TypeResolverTest]"){}
void onRun() override;
};

View File

@ -24,12 +24,12 @@
#include "AnyTest.hpp"
#include "oatpp/data/mapping/type/Any.hpp"
#include "oatpp/data/type/Any.hpp"
#include "oatpp/json/ObjectMapper.hpp"
#include "oatpp/macro/codegen.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace {
@ -61,7 +61,7 @@ void AnyTest::onRun() {
OATPP_LOGI(TAG, "Test default constructor...")
oatpp::Any any;
OATPP_ASSERT(!any)
OATPP_ASSERT(any.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == nullptr)
OATPP_LOGI(TAG, "OK")
}
@ -70,7 +70,7 @@ void AnyTest::onRun() {
OATPP_LOGI(TAG, "Test nullptr constructor...")
oatpp::Any any(nullptr);
OATPP_ASSERT(!any)
OATPP_ASSERT(any.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == nullptr)
OATPP_LOGI(TAG, "OK")
}
@ -79,8 +79,8 @@ void AnyTest::onRun() {
OATPP_LOGI(TAG, "Test retrieve()...")
oatpp::Any any(oatpp::String("Hello Any!"));
OATPP_ASSERT(any)
OATPP_ASSERT(any.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(any.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == oatpp::data::type::__class::String::getType())
auto str = any.retrieve<oatpp::String>();
OATPP_ASSERT(str == "Hello Any!")
OATPP_LOGI(TAG, "OK")
@ -91,14 +91,14 @@ void AnyTest::onRun() {
oatpp::Any any(oatpp::Int32(32));
OATPP_ASSERT(any)
OATPP_ASSERT(any.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::Int32::getType())
OATPP_ASSERT(any.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == oatpp::data::type::__class::Int32::getType())
any.store(oatpp::String("Hello Any!"));
OATPP_ASSERT(any)
OATPP_ASSERT(any.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(any.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == oatpp::data::type::__class::String::getType())
auto str = any.retrieve<oatpp::String>();
OATPP_ASSERT(str == "Hello Any!")
@ -109,7 +109,7 @@ void AnyTest::onRun() {
OATPP_LOGI(TAG, "Test retrieve() class check...")
oatpp::Any any(Dto1::createShared());
OATPP_ASSERT(any)
OATPP_ASSERT(any.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any.getStoredType() == Object<Dto1>::Class::getType())
bool wasError = false;
@ -134,11 +134,11 @@ void AnyTest::onRun() {
OATPP_ASSERT(any1)
OATPP_ASSERT(any2)
OATPP_ASSERT(any1.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any2.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any1.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any2.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any1.getStoredType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(any2.getStoredType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(any1.getStoredType() == oatpp::data::type::__class::String::getType())
OATPP_ASSERT(any2.getStoredType() == oatpp::data::type::__class::String::getType())
OATPP_ASSERT(any1 == any2)
OATPP_ASSERT(any1.getPtr().get() != any2.getPtr().get())
@ -161,11 +161,11 @@ void AnyTest::onRun() {
OATPP_ASSERT(!any1)
OATPP_ASSERT(any2)
OATPP_ASSERT(any1.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any2.getValueType() == oatpp::data::mapping::type::__class::Any::getType())
OATPP_ASSERT(any1.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any2.getValueType() == oatpp::data::type::__class::Any::getType())
OATPP_ASSERT(any1.getStoredType() == nullptr)
OATPP_ASSERT(any2.getStoredType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(any2.getStoredType() == oatpp::data::type::__class::String::getType())
OATPP_ASSERT(any1 != any2)
OATPP_ASSERT(any1.getPtr().get() != any2.getPtr().get())
@ -180,4 +180,4 @@ void AnyTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_AnyTest_hpp
#define oatpp_data_mapping_type_AnyTest_hpp
#ifndef oatpp_data_type_AnyTest_hpp
#define oatpp_data_type_AnyTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class AnyTest : public oatpp::test::UnitTest {
public:
AnyTest():UnitTest("TEST[data::mapping::type::AnyTest]"){}
AnyTest():UnitTest("TEST[data::type::AnyTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_AnyTest_hpp */
#endif /* oatpp_data_type_AnyTest_hpp */

View File

@ -29,7 +29,7 @@
#include <unordered_map>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
#include OATPP_CODEGEN_BEGIN(DTO)
@ -142,11 +142,11 @@ void EnumTest::onRun() {
OATPP_ASSERT(oatpp::Enum<Enum2>::NotNull::AsString::Interpreter::notNull == true)
OATPP_ASSERT(oatpp::Enum<Enum2>::NotNull::AsNumber::Interpreter::notNull == true)
auto pd1 = static_cast<const oatpp::data::mapping::type::__class::AbstractEnum::PolymorphicDispatcher*>(
auto pd1 = static_cast<const oatpp::data::type::__class::AbstractEnum::PolymorphicDispatcher*>(
oatpp::Enum<Enum2>::Class::getType()->polymorphicDispatcher
);
auto pd2 = static_cast<const oatpp::data::mapping::type::__class::AbstractEnum::PolymorphicDispatcher*>(
auto pd2 = static_cast<const oatpp::data::type::__class::AbstractEnum::PolymorphicDispatcher*>(
oatpp::Enum<Enum2>::NotNull::Class::getType()->polymorphicDispatcher
);
@ -164,17 +164,17 @@ void EnumTest::onRun() {
{
OATPP_LOGI(TAG, "Test Interpreter AsString...")
oatpp::data::mapping::type::EnumInterpreterError e = oatpp::data::mapping::type::EnumInterpreterError::OK;
oatpp::data::type::EnumInterpreterError e = oatpp::data::type::EnumInterpreterError::OK;
auto inter = oatpp::Enum<Enum2>::AsString::Interpreter::toInterpretation(oatpp::Enum<Enum2>::AsString(Enum2::NAME_1), e);
OATPP_ASSERT(inter.getValueType() == oatpp::String::Class::getType())
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK)
OATPP_ASSERT(e == oatpp::data::type::EnumInterpreterError::OK)
auto interValue = inter.cast<oatpp::String>();
OATPP_ASSERT(interValue == "name-1")
oatpp::Void voidValue = oatpp::Enum<Enum2>::AsString::Interpreter::fromInterpretation(interValue, e);
OATPP_ASSERT(voidValue.getValueType() == oatpp::Enum<Enum2>::AsString::Class::getType())
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK)
OATPP_ASSERT(e == oatpp::data::type::EnumInterpreterError::OK)
auto value = voidValue.cast<oatpp::Enum<Enum2>::AsString>();
OATPP_ASSERT(value == Enum2::NAME_1)
@ -183,17 +183,17 @@ void EnumTest::onRun() {
{
OATPP_LOGI(TAG, "Test Interpreter AsNumber...")
oatpp::data::mapping::type::EnumInterpreterError e = oatpp::data::mapping::type::EnumInterpreterError::OK;
oatpp::data::type::EnumInterpreterError e = oatpp::data::type::EnumInterpreterError::OK;
auto inter = oatpp::Enum<Enum2>::AsNumber::Interpreter::toInterpretation(oatpp::Enum<Enum2>::AsNumber(Enum2::NAME_1), e);
OATPP_ASSERT(inter.getValueType() == oatpp::Int32::Class::getType())
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK)
OATPP_ASSERT(e == oatpp::data::type::EnumInterpreterError::OK)
auto interValue = inter.cast<oatpp::Int32>();
OATPP_ASSERT(interValue == static_cast<v_int32>(Enum2::NAME_1))
oatpp::Void voidValue = oatpp::Enum<Enum2>::AsNumber::Interpreter::fromInterpretation(interValue, e);
OATPP_ASSERT(voidValue.getValueType() == oatpp::Enum<Enum2>::AsNumber::Class::getType())
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK)
OATPP_ASSERT(e == oatpp::data::type::EnumInterpreterError::OK)
auto value = voidValue.cast<oatpp::Enum<Enum2>::AsNumber>();
OATPP_ASSERT(value == Enum2::NAME_1)
@ -303,4 +303,4 @@ void EnumTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_EnumTest_hpp
#define oatpp_data_mapping_type_EnumTest_hpp
#ifndef oatpp_data_type_EnumTest_hpp
#define oatpp_data_type_EnumTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class EnumTest : public oatpp::test::UnitTest {
public:
EnumTest():UnitTest("TEST[data::mapping::type::EnumTest]"){}
EnumTest():UnitTest("TEST[data::type::EnumTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_EnumTest_hpp */
#endif /* oatpp_data_type_EnumTest_hpp */

View File

@ -29,7 +29,7 @@
#include "oatpp/Types.hpp"
#include "oatpp/macro/codegen.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace {
@ -51,8 +51,8 @@ namespace __class {
class LineClass;
}
typedef oatpp::data::mapping::type::Primitive<VPoint, __class::PointClass> Point;
typedef oatpp::data::mapping::type::Primitive<VLine, __class::LineClass> Line;
typedef oatpp::data::type::Primitive<VPoint, __class::PointClass> Point;
typedef oatpp::data::type::Primitive<VLine, __class::LineClass> Line;
namespace __class {
@ -176,14 +176,14 @@ void InterpretationTest::onRun() {
oatpp::json::ObjectMapper mapper;
{
auto config = mapper.getSerializer()->getConfig();
config->enabledInterpretations = {"test"};
config->useBeautifier = false;
auto& config = mapper.serializerConfig();
config.mapper.enabledInterpretations = {"test"};
config.json.useBeautifier = false;
}
{
auto config = mapper.getDeserializer()->getConfig();
config->enabledInterpretations = {"test"};
auto& config = mapper.deserializerConfig();
config.mapper.enabledInterpretations = {"test"};
}
Point p1 ({1, 2, 3});
@ -243,4 +243,4 @@ void InterpretationTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_InterpretationTest_hpp
#define oatpp_data_mapping_type_InterpretationTest_hpp
#ifndef oatpp_data_type_InterpretationTest_hpp
#define oatpp_data_type_InterpretationTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class InterpretationTest : public oatpp::test::UnitTest {
public:
InterpretationTest():UnitTest("TEST[data::mapping::type::InterpretationTest]"){}
InterpretationTest():UnitTest("TEST[data::type::InterpretationTest]"){}
void onRun() override;
};
}}}}
}}}
#endif // oatpp_data_mapping_type_InterpretationTest_hpp
#endif // oatpp_data_type_InterpretationTest_hpp

View File

@ -26,7 +26,7 @@
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
void ListTest::onRun() {
@ -38,7 +38,7 @@ void ListTest::onRun() {
OATPP_ASSERT(list == nullptr)
OATPP_ASSERT(list.get() == nullptr)
OATPP_ASSERT(list.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id)
OATPP_ASSERT(list.getValueType()->classId.id == oatpp::data::type::__class::AbstractList::CLASS_ID.id)
OATPP_ASSERT(list.getValueType()->params.size() == 1)
OATPP_ASSERT(list.getValueType()->params.front() == oatpp::String::Class::getType())
OATPP_LOGI(TAG, "OK")
@ -53,7 +53,7 @@ void ListTest::onRun() {
OATPP_ASSERT(list->size() == 0)
OATPP_ASSERT(list.get() != nullptr)
OATPP_ASSERT(list.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id)
OATPP_ASSERT(list.getValueType()->classId.id == oatpp::data::type::__class::AbstractList::CLASS_ID.id)
OATPP_ASSERT(list.getValueType()->params.size() == 1)
OATPP_ASSERT(list.getValueType()->params.front() == oatpp::String::Class::getType())
OATPP_LOGI(TAG, "OK")
@ -68,7 +68,7 @@ void ListTest::onRun() {
OATPP_ASSERT(list->size() == 0)
OATPP_ASSERT(list.get() != nullptr)
OATPP_ASSERT(list.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id)
OATPP_ASSERT(list.getValueType()->classId.id == oatpp::data::type::__class::AbstractList::CLASS_ID.id)
OATPP_LOGI(TAG, "OK")
}
@ -140,7 +140,7 @@ void ListTest::onRun() {
OATPP_LOGI(TAG, "test polymorphicDispatcher...")
oatpp::List<oatpp::String> list = {"a", "b", "c"};
auto polymorphicDispatcher = static_cast<const oatpp::data::mapping::type::__class::Collection::PolymorphicDispatcher*>(
auto polymorphicDispatcher = static_cast<const oatpp::data::type::__class::Collection::PolymorphicDispatcher*>(
list.getValueType()->polymorphicDispatcher
);
@ -157,4 +157,4 @@ void ListTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_ListTest_hpp
#define oatpp_data_mapping_type_ListTest_hpp
#ifndef oatpp_data_type_ListTest_hpp
#define oatpp_data_type_ListTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class ListTest : public oatpp::test::UnitTest {
public:
ListTest():UnitTest("TEST[data::mapping::type::ListTest]"){}
ListTest():UnitTest("TEST[data::type::ListTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_ListTest_hpp */
#endif /* oatpp_data_type_ListTest_hpp */

View File

@ -33,7 +33,7 @@
#include <thread>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace {
@ -200,7 +200,7 @@ void ObjectTest::onRun() {
OATPP_LOGI(TAG, "Test Meta 1...")
auto type = Object<DtoA>::Class::getType();
auto dispatcher = static_cast<const oatpp::data::mapping::type::__class::AbstractObject::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto dispatcher = static_cast<const oatpp::data::type::__class::AbstractObject::PolymorphicDispatcher*>(type->polymorphicDispatcher);
const auto& propsMap = dispatcher->getProperties()->getMap();
OATPP_ASSERT(propsMap.size() == 1)
@ -217,7 +217,7 @@ void ObjectTest::onRun() {
OATPP_LOGI(TAG, "Test Meta 2...")
auto type = Object<DtoB>::Class::getType();
auto dispatcher = static_cast<const oatpp::data::mapping::type::__class::AbstractObject::PolymorphicDispatcher*>(type->polymorphicDispatcher);
auto dispatcher = static_cast<const oatpp::data::type::__class::AbstractObject::PolymorphicDispatcher*>(type->polymorphicDispatcher);
const auto& propsMap = dispatcher->getProperties()->getMap();
OATPP_ASSERT(propsMap.size() == 2)
@ -242,7 +242,7 @@ void ObjectTest::onRun() {
Object<DtoA> a;
OATPP_ASSERT(!a)
OATPP_ASSERT(a == nullptr)
OATPP_ASSERT(a.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id)
OATPP_ASSERT(a.getValueType()->classId.id == oatpp::data::type::__class::AbstractObject::CLASS_ID.id)
OATPP_LOGI(TAG, "OK")
}
@ -574,4 +574,4 @@ void ObjectTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_ObjectTest_hpp
#define oatpp_data_mapping_type_ObjectTest_hpp
#ifndef oatpp_data_type_ObjectTest_hpp
#define oatpp_data_type_ObjectTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class ObjectTest : public oatpp::test::UnitTest {
public:
ObjectTest():UnitTest("TEST[data::mapping::type::ObjectTest]"){}
ObjectTest():UnitTest("TEST[data::type::ObjectTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_ObjectTest_hpp */
#endif /* oatpp_data_type_ObjectTest_hpp */

View File

@ -25,12 +25,12 @@
#include "ObjectWrapperTest.hpp"
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace {
template<class T, class Clazz = oatpp::data::mapping::type::__class::Void>
using TestWrapper = oatpp::data::mapping::type::ObjectWrapper<T, Clazz>;
template<class T, class Clazz = oatpp::data::type::__class::Void>
using TestWrapper = oatpp::data::type::ObjectWrapper<T, Clazz>;
}
@ -41,47 +41,47 @@ void ObjectWrapperTest::onRun() {
TestWrapper<std::string> pw;
OATPP_ASSERT(!pw)
OATPP_ASSERT(pw == nullptr)
OATPP_ASSERT(pw.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw.getValueType() == oatpp::data::type::__class::Void::getType())
OATPP_LOGI(TAG, "OK")
}
{
OATPP_LOGI(TAG, "Check default valueType is assigned (specified tparam Clazz)...")
TestWrapper<std::string, oatpp::data::mapping::type::__class::String> pw;
TestWrapper<std::string, oatpp::data::type::__class::String> pw;
OATPP_ASSERT(!pw)
OATPP_ASSERT(pw == nullptr)
OATPP_ASSERT(pw.getValueType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(pw.getValueType() == oatpp::data::type::__class::String::getType())
OATPP_LOGI(TAG, "OK")
}
{
OATPP_LOGI(TAG, "Check valueType is assigned from constructor...")
TestWrapper<std::string> pw(oatpp::data::mapping::type::__class::String::getType());
TestWrapper<std::string> pw(oatpp::data::type::__class::String::getType());
OATPP_ASSERT(!pw)
OATPP_ASSERT(pw == nullptr)
OATPP_ASSERT(pw.getValueType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(pw.getValueType() == oatpp::data::type::__class::String::getType())
OATPP_LOGI(TAG, "OK")
}
{
OATPP_LOGI(TAG, "Check valueType is assigned from copy constructor...")
TestWrapper<std::string> pw1(oatpp::data::mapping::type::__class::String::getType());
TestWrapper<std::string> pw1(oatpp::data::type::__class::String::getType());
TestWrapper<std::string> pw2(pw1);
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::String::getType())
OATPP_LOGI(TAG, "OK")
}
{
OATPP_LOGI(TAG, "Check valueType is assigned from move constructor...")
TestWrapper<std::string> pw1(oatpp::data::mapping::type::__class::String::getType());
TestWrapper<std::string> pw1(oatpp::data::type::__class::String::getType());
TestWrapper<std::string> pw2(std::move(pw1));
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::String::getType())
OATPP_LOGI(TAG, "OK")
}
{
OATPP_LOGI(TAG, "Check valueType is NOT assigned from copy-assign operator...")
TestWrapper<std::string> pw1(oatpp::data::mapping::type::__class::String::getType());
TestWrapper<std::string> pw1(oatpp::data::type::__class::String::getType());
TestWrapper<std::string> pw2;
bool throws = false;
try {
@ -89,14 +89,14 @@ void ObjectWrapperTest::onRun() {
} catch (std::runtime_error&) {
throws = true;
}
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::Void::getType())
OATPP_ASSERT(throws)
OATPP_LOGI(TAG, "OK")
}
{
OATPP_LOGI(TAG, "Check valueType is NOT assigned from move-assign operator...")
TestWrapper<std::string> pw1(oatpp::data::mapping::type::__class::String::getType());
TestWrapper<std::string> pw1(oatpp::data::type::__class::String::getType());
TestWrapper<std::string> pw2;
bool throws = false;
try {
@ -104,7 +104,7 @@ void ObjectWrapperTest::onRun() {
} catch (std::runtime_error&) {
throws = true;
}
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::Void::getType())
OATPP_ASSERT(throws)
OATPP_LOGI(TAG, "OK")
}
@ -114,12 +114,12 @@ void ObjectWrapperTest::onRun() {
TestWrapper<std::string> pw1;
OATPP_ASSERT(!pw1)
OATPP_ASSERT(pw1 == nullptr)
OATPP_ASSERT(pw1.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw1.getValueType() == oatpp::data::type::__class::Void::getType())
TestWrapper<std::string> pw2 = std::make_shared<std::string>("Hello!");
OATPP_ASSERT(pw2)
OATPP_ASSERT(pw2 != nullptr)
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::Void::getType())
pw1 = pw2;
@ -136,15 +136,15 @@ void ObjectWrapperTest::onRun() {
{
OATPP_LOGI(TAG, "Check != operator...")
TestWrapper<std::string, oatpp::data::mapping::type::__class::String> pw1(std::make_shared<std::string>("Hello!"));
TestWrapper<std::string, oatpp::data::type::__class::String> pw1(std::make_shared<std::string>("Hello!"));
OATPP_ASSERT(pw1)
OATPP_ASSERT(pw1 != nullptr)
OATPP_ASSERT(pw1.getValueType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(pw1.getValueType() == oatpp::data::type::__class::String::getType())
TestWrapper<std::string, oatpp::data::mapping::type::__class::String> pw2(std::make_shared<std::string>("Hello!"));
TestWrapper<std::string, oatpp::data::type::__class::String> pw2(std::make_shared<std::string>("Hello!"));
OATPP_ASSERT(pw2)
OATPP_ASSERT(pw2 != nullptr)
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::String::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::String::getType())
OATPP_ASSERT(pw1 != pw2)
OATPP_ASSERT(pw1.get() != pw2.get())
@ -156,12 +156,12 @@ void ObjectWrapperTest::onRun() {
TestWrapper<std::string> pw1;
OATPP_ASSERT(!pw1)
OATPP_ASSERT(pw1 == nullptr)
OATPP_ASSERT(pw1.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw1.getValueType() == oatpp::data::type::__class::Void::getType())
TestWrapper<std::string> pw2 = std::make_shared<std::string>("Hello!");
OATPP_ASSERT(pw2)
OATPP_ASSERT(pw2 != nullptr)
OATPP_ASSERT(pw2.getValueType() == oatpp::data::mapping::type::__class::Void::getType())
OATPP_ASSERT(pw2.getValueType() == oatpp::data::type::__class::Void::getType())
pw1 = std::move(pw2);
@ -197,4 +197,4 @@ void ObjectWrapperTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_ObjectWrapperTest_hpp
#define oatpp_data_mapping_type_ObjectWrapperTest_hpp
#ifndef oatpp_data_type_ObjectWrapperTest_hpp
#define oatpp_data_type_ObjectWrapperTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class ObjectWrapperTest : public oatpp::test::UnitTest {
public:
ObjectWrapperTest():UnitTest("TEST[data::mapping::type::ObjectWrapperTest]"){}
ObjectWrapperTest():UnitTest("TEST[data::type::ObjectWrapperTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_ObjectWrapperTest_hpp */
#endif /* oatpp_data_type_ObjectWrapperTest_hpp */

View File

@ -26,7 +26,7 @@
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
void PairListTest::onRun() {
@ -38,7 +38,7 @@ void PairListTest::onRun() {
OATPP_ASSERT(map == nullptr)
OATPP_ASSERT(map.get() == nullptr)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::type::__class::AbstractPairList::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->params.size() == 2)
auto it = map.getValueType()->params.begin();
OATPP_ASSERT(*it++ == oatpp::String::Class::getType())
@ -55,7 +55,7 @@ void PairListTest::onRun() {
OATPP_ASSERT(map->size() == 0)
OATPP_ASSERT(map.get() != nullptr)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::type::__class::AbstractPairList::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->params.size() == 2)
auto it = map.getValueType()->params.begin();
OATPP_ASSERT(*it++ == oatpp::String::Class::getType())
@ -72,7 +72,7 @@ void PairListTest::onRun() {
OATPP_ASSERT(map->size() == 0)
OATPP_ASSERT(map.get() != nullptr)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::type::__class::AbstractPairList::CLASS_ID.id)
OATPP_LOGI(TAG, "OK")
}
@ -148,7 +148,7 @@ void PairListTest::onRun() {
OATPP_LOGI(TAG, "test polymorphicDispatcher...")
oatpp::Fields<String> map = {{"key1", "a"}, {"key2", "b"}, {"key3", "c"}};
auto polymorphicDispatcher = static_cast<const typename oatpp::data::mapping::type::__class::Map::PolymorphicDispatcher*>(
auto polymorphicDispatcher = static_cast<const typename oatpp::data::type::__class::Map::PolymorphicDispatcher*>(
map.getValueType()->polymorphicDispatcher
);
@ -165,4 +165,4 @@ void PairListTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_PairListTest_hpp
#define oatpp_data_mapping_type_PairListTest_hpp
#ifndef oatpp_data_type_PairListTest_hpp
#define oatpp_data_type_PairListTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class PairListTest : public oatpp::test::UnitTest {
public:
PairListTest():UnitTest("TEST[data::mapping::type::PairListTest]"){}
PairListTest():UnitTest("TEST[data::type::PairListTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_PairListTest_hpp */
#endif /* oatpp_data_type_PairListTest_hpp */

View File

@ -26,7 +26,7 @@
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace {
@ -254,4 +254,4 @@ void PrimitiveTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_PrimitiveTest_hpp
#define oatpp_data_mapping_type_PrimitiveTest_hpp
#ifndef oatpp_data_type_PrimitiveTest_hpp
#define oatpp_data_type_PrimitiveTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class PrimitiveTest : public oatpp::test::UnitTest {
public:
PrimitiveTest():UnitTest("TEST[data::mapping::type::PrimitiveTest]"){}
PrimitiveTest():UnitTest("TEST[data::type::PrimitiveTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_PrimitiveTest_hpp */
#endif /* oatpp_data_type_PrimitiveTest_hpp */

View File

@ -28,7 +28,7 @@
#include <functional>
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
void StringTest::onRun() {
@ -316,4 +316,4 @@ void StringTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_StringTest_hpp
#define oatpp_data_mapping_type_StringTest_hpp
#ifndef oatpp_data_type_StringTest_hpp
#define oatpp_data_type_StringTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class StringTest : public oatpp::test::UnitTest {
public:
StringTest():UnitTest("TEST[data::mapping::type::StringTest]"){}
StringTest():UnitTest("TEST[data::type::StringTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_StringTest_hpp */
#endif /* oatpp_data_type_StringTest_hpp */

View File

@ -27,7 +27,7 @@
#include "oatpp/macro/codegen.hpp"
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
namespace {
@ -68,52 +68,52 @@ void TypeTest::onRun() {
auto obj = TestDto::createShared();
OATPP_LOGV(TAG, "type: '%s'", obj->field_string.getValueType()->classId.name)
OATPP_ASSERT(obj->field_string.getValueType()->classId == oatpp::data::mapping::type::__class::String::CLASS_ID)
OATPP_ASSERT(obj->field_string.getValueType()->classId == oatpp::data::type::__class::String::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_int8.getValueType()->classId.name)
OATPP_ASSERT(obj->field_int8.getValueType()->classId == oatpp::data::mapping::type::__class::Int8::CLASS_ID)
OATPP_ASSERT(obj->field_int8.getValueType()->classId == oatpp::data::type::__class::Int8::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_int16.getValueType()->classId.name)
OATPP_ASSERT(obj->field_int16.getValueType()->classId == oatpp::data::mapping::type::__class::Int16::CLASS_ID)
OATPP_ASSERT(obj->field_int16.getValueType()->classId == oatpp::data::type::__class::Int16::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_int32.getValueType()->classId.name)
OATPP_ASSERT(obj->field_int32.getValueType()->classId == oatpp::data::mapping::type::__class::Int32::CLASS_ID)
OATPP_ASSERT(obj->field_int32.getValueType()->classId == oatpp::data::type::__class::Int32::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_int64.getValueType()->classId.name)
OATPP_ASSERT(obj->field_int64.getValueType()->classId == oatpp::data::mapping::type::__class::Int64::CLASS_ID)
OATPP_ASSERT(obj->field_int64.getValueType()->classId == oatpp::data::type::__class::Int64::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_float32.getValueType()->classId.name)
OATPP_ASSERT(obj->field_float32.getValueType()->classId == oatpp::data::mapping::type::__class::Float32::CLASS_ID)
OATPP_ASSERT(obj->field_float32.getValueType()->classId == oatpp::data::type::__class::Float32::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_float64.getValueType()->classId.name)
OATPP_ASSERT(obj->field_float64.getValueType()->classId == oatpp::data::mapping::type::__class::Float64::CLASS_ID)
OATPP_ASSERT(obj->field_float64.getValueType()->classId == oatpp::data::type::__class::Float64::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_boolean.getValueType()->classId.name)
OATPP_ASSERT(obj->field_boolean.getValueType()->classId == oatpp::data::mapping::type::__class::Boolean::CLASS_ID)
OATPP_ASSERT(obj->field_boolean.getValueType()->classId == oatpp::data::type::__class::Boolean::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_string.getValueType()->classId.name)
OATPP_ASSERT(obj->field_list_string.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID)
OATPP_ASSERT(obj->field_list_string.getValueType()->classId == oatpp::data::type::__class::AbstractList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_int32.getValueType()->classId.name)
OATPP_ASSERT(obj->field_list_int32.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID)
OATPP_ASSERT(obj->field_list_int32.getValueType()->classId == oatpp::data::type::__class::AbstractList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_int64.getValueType()->classId.name)
OATPP_ASSERT(obj->field_list_int64.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID)
OATPP_ASSERT(obj->field_list_int64.getValueType()->classId == oatpp::data::type::__class::AbstractList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_float32.getValueType()->classId.name)
OATPP_ASSERT(obj->field_list_float32.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID)
OATPP_ASSERT(obj->field_list_float32.getValueType()->classId == oatpp::data::type::__class::AbstractList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_float64.getValueType()->classId.name)
OATPP_ASSERT(obj->field_list_float64.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID)
OATPP_ASSERT(obj->field_list_float64.getValueType()->classId == oatpp::data::type::__class::AbstractList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_list_boolean.getValueType()->classId.name)
OATPP_ASSERT(obj->field_list_boolean.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID)
OATPP_ASSERT(obj->field_list_boolean.getValueType()->classId == oatpp::data::type::__class::AbstractList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->field_map_string_string.getValueType()->classId.name)
OATPP_ASSERT(obj->field_map_string_string.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID)
OATPP_ASSERT(obj->field_map_string_string.getValueType()->classId == oatpp::data::type::__class::AbstractPairList::CLASS_ID)
OATPP_LOGV(TAG, "type: '%s'", obj->obj1.getValueType()->classId.name)
OATPP_ASSERT(obj->obj1.getValueType()->classId == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID)
OATPP_ASSERT(obj->obj1.getValueType()->classId == oatpp::data::type::__class::AbstractObject::CLASS_ID)
OATPP_ASSERT(oatpp::String::Class::getType()->extends(oatpp::String::Class::getType()))
OATPP_ASSERT(oatpp::Int32::Class::getType()->extends(oatpp::Int32::Class::getType()))
@ -121,4 +121,4 @@ void TypeTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_TypeTest_hpp
#define oatpp_data_mapping_type_TypeTest_hpp
#ifndef oatpp_data_type_TypeTest_hpp
#define oatpp_data_type_TypeTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class TypeTest : public oatpp::test::UnitTest {
public:
TypeTest():UnitTest("TEST[data::mapping::type::TypeTest]"){}
TypeTest():UnitTest("TEST[data::type::TypeTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_TypeTest_hpp */
#endif /* oatpp_data_type_TypeTest_hpp */

View File

@ -26,7 +26,7 @@
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
void UnorderedMapTest::onRun() {
@ -38,7 +38,7 @@ void UnorderedMapTest::onRun() {
OATPP_ASSERT(map == nullptr)
OATPP_ASSERT(map.get() == nullptr)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::type::__class::AbstractUnorderedMap::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->params.size() == 2)
auto it = map.getValueType()->params.begin();
OATPP_ASSERT(*it++ == oatpp::String::Class::getType())
@ -55,7 +55,7 @@ void UnorderedMapTest::onRun() {
OATPP_ASSERT(map->size() == 0)
OATPP_ASSERT(map.get() != nullptr)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::type::__class::AbstractUnorderedMap::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->params.size() == 2)
auto it = map.getValueType()->params.begin();
OATPP_ASSERT(*it++ == oatpp::String::Class::getType())
@ -72,7 +72,7 @@ void UnorderedMapTest::onRun() {
OATPP_ASSERT(map->size() == 0)
OATPP_ASSERT(map.get() != nullptr)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID.id)
OATPP_ASSERT(map.getValueType()->classId.id == oatpp::data::type::__class::AbstractUnorderedMap::CLASS_ID.id)
OATPP_LOGI(TAG, "OK")
}
@ -144,7 +144,7 @@ void UnorderedMapTest::onRun() {
OATPP_LOGI(TAG, "test polymorphicDispatcher...")
oatpp::UnorderedFields<String> map = {{"key1", "a"}, {"key2", "b"}, {"key3", "c"}};
auto polymorphicDispatcher = static_cast<const typename oatpp::data::mapping::type::__class::Map::PolymorphicDispatcher*>(
auto polymorphicDispatcher = static_cast<const typename oatpp::data::type::__class::Map::PolymorphicDispatcher*>(
map.getValueType()->polymorphicDispatcher
);
@ -160,4 +160,4 @@ void UnorderedMapTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_UnorderedMapTest_hpp
#define oatpp_data_mapping_type_UnorderedMapTest_hpp
#ifndef oatpp_data_type_UnorderedMapTest_hpp
#define oatpp_data_type_UnorderedMapTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class UnorderedMapTest : public oatpp::test::UnitTest {
public:
UnorderedMapTest():UnitTest("TEST[data::mapping::type::UnorderedMapTest]"){}
UnorderedMapTest():UnitTest("TEST[data::type::UnorderedMapTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_UnorderedMapTest_hpp */
#endif /* oatpp_data_type_UnorderedMapTest_hpp */

View File

@ -26,7 +26,7 @@
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
void UnorderedSetTest::onRun() {
@ -39,7 +39,7 @@ void UnorderedSetTest::onRun() {
OATPP_ASSERT(set == nullptr)
OATPP_ASSERT(set.get() == nullptr)
OATPP_ASSERT(set.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id)
OATPP_ASSERT(set.getValueType()->classId.id == oatpp::data::type::__class::AbstractUnorderedSet::CLASS_ID.id)
OATPP_ASSERT(set.getValueType()->params.size() == 1)
OATPP_ASSERT(set.getValueType()->params.front() == oatpp::String::Class::getType())
OATPP_LOGI(TAG, "OK")
@ -54,7 +54,7 @@ void UnorderedSetTest::onRun() {
OATPP_ASSERT(set->size() == 0)
OATPP_ASSERT(set.get() != nullptr)
OATPP_ASSERT(set.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id)
OATPP_ASSERT(set.getValueType()->classId.id == oatpp::data::type::__class::AbstractUnorderedSet::CLASS_ID.id)
OATPP_ASSERT(set.getValueType()->params.size() == 1)
OATPP_ASSERT(set.getValueType()->params.front() == oatpp::String::Class::getType())
OATPP_LOGI(TAG, "OK")
@ -69,7 +69,7 @@ void UnorderedSetTest::onRun() {
OATPP_ASSERT(set->size() == 0)
OATPP_ASSERT(set.get() != nullptr)
OATPP_ASSERT(set.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id)
OATPP_ASSERT(set.getValueType()->classId.id == oatpp::data::type::__class::AbstractUnorderedSet::CLASS_ID.id)
OATPP_LOGI(TAG, "OK")
}
@ -120,7 +120,7 @@ void UnorderedSetTest::onRun() {
OATPP_LOGI(TAG, "test polymorphicDispatcher...")
oatpp::UnorderedSet<oatpp::String> set = {"a", "b", "c"};
auto polymorphicDispatcher = static_cast<const typename oatpp::data::mapping::type::__class::Collection::PolymorphicDispatcher*>(
auto polymorphicDispatcher = static_cast<const typename oatpp::data::type::__class::Collection::PolymorphicDispatcher*>(
set.getValueType()->polymorphicDispatcher
);
@ -141,4 +141,4 @@ void UnorderedSetTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_UnorderedSetTest_hpp
#define oatpp_data_mapping_type_UnorderedSetTest_hpp
#ifndef oatpp_data_type_UnorderedSetTest_hpp
#define oatpp_data_type_UnorderedSetTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class UnorderedSetTest : public oatpp::test::UnitTest {
public:
UnorderedSetTest():UnitTest("TEST[data::mapping::type::UnorderedSetTest]"){}
UnorderedSetTest():UnitTest("TEST[data::type::UnorderedSetTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_UnorderedSetTest_hpp */
#endif /* oatpp_data_type_UnorderedSetTest_hpp */

View File

@ -26,7 +26,7 @@
#include "oatpp/Types.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
void VectorTest::onRun() {
@ -38,7 +38,7 @@ void VectorTest::onRun() {
OATPP_ASSERT(vector == nullptr)
OATPP_ASSERT(vector.get() == nullptr)
OATPP_ASSERT(vector.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractVector::CLASS_ID.id)
OATPP_ASSERT(vector.getValueType()->classId.id == oatpp::data::type::__class::AbstractVector::CLASS_ID.id)
OATPP_ASSERT(vector.getValueType()->params.size() == 1)
OATPP_ASSERT(vector.getValueType()->params.front() == oatpp::String::Class::getType())
OATPP_LOGI(TAG, "OK")
@ -53,7 +53,7 @@ void VectorTest::onRun() {
OATPP_ASSERT(vector->size() == 0)
OATPP_ASSERT(vector.get() != nullptr)
OATPP_ASSERT(vector.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractVector::CLASS_ID.id)
OATPP_ASSERT(vector.getValueType()->classId.id == oatpp::data::type::__class::AbstractVector::CLASS_ID.id)
OATPP_ASSERT(vector.getValueType()->params.size() == 1)
OATPP_ASSERT(vector.getValueType()->params.front() == oatpp::String::Class::getType())
OATPP_LOGI(TAG, "OK")
@ -68,7 +68,7 @@ void VectorTest::onRun() {
OATPP_ASSERT(vector->size() == 0)
OATPP_ASSERT(vector.get() != nullptr)
OATPP_ASSERT(vector.getValueType()->classId.id == oatpp::data::mapping::type::__class::AbstractVector::CLASS_ID.id)
OATPP_ASSERT(vector.getValueType()->classId.id == oatpp::data::type::__class::AbstractVector::CLASS_ID.id)
OATPP_LOGI(TAG, "OK")
}
@ -140,7 +140,7 @@ void VectorTest::onRun() {
OATPP_LOGI(TAG, "test polymorphicDispatcher...")
oatpp::Vector<oatpp::String> vector = {"a", "b", "c"};
auto polymorphicDispatcher = static_cast<const oatpp::data::mapping::type::__class::Collection::PolymorphicDispatcher*>(
auto polymorphicDispatcher = static_cast<const oatpp::data::type::__class::Collection::PolymorphicDispatcher*>(
vector.getValueType()->polymorphicDispatcher
);
@ -157,4 +157,4 @@ void VectorTest::onRun() {
}
}}}}
}}}

View File

@ -22,21 +22,21 @@
*
***************************************************************************/
#ifndef oatpp_data_mapping_type_VectorTest_hpp
#define oatpp_data_mapping_type_VectorTest_hpp
#ifndef oatpp_data_type_VectorTest_hpp
#define oatpp_data_type_VectorTest_hpp
#include "oatpp-test/UnitTest.hpp"
namespace oatpp { namespace data { namespace mapping { namespace type {
namespace oatpp { namespace data { namespace type {
class VectorTest : public oatpp::test::UnitTest {
public:
VectorTest():UnitTest("TEST[data::mapping::type::VectorTest]"){}
VectorTest():UnitTest("TEST[data::type::VectorTest]"){}
void onRun() override;
};
}}}}
}}}
#endif /* oatpp_data_mapping_type_VectorTest_hpp */
#endif /* oatpp_data_type_VectorTest_hpp */

View File

@ -60,4 +60,4 @@ void BooleanTest::onRun() {
}
}
}}
}}

View File

@ -73,17 +73,16 @@ void DTOMapperPerfTest::onRun() {
v_int32 numIterations = 1000000;
auto serializer2 = std::make_shared<oatpp::json::Serializer>();
auto mapper = oatpp::json::ObjectMapper::createShared();
oatpp::json::ObjectMapper mapper;
auto test1 = Test1::createTestInstance();
auto test1_Text = mapper->writeToString(test1);
auto test1_Text = mapper.writeToString(test1);
OATPP_LOGV(TAG, "json='%s'", test1_Text->c_str())
{
oatpp::test::PerformanceChecker checker("Serializer");
for(v_int32 i = 0; i < numIterations; i ++) {
mapper->writeToString(test1);
mapper.writeToString(test1);
}
}
@ -92,7 +91,7 @@ void DTOMapperPerfTest::onRun() {
oatpp::utils::parser::Caret caret(test1_Text);
for(v_int32 i = 0; i < numIterations; i ++) {
caret.setPosition(0);
mapper->readFromCaret<oatpp::Object<Test1>>(caret);
mapper.readFromCaret<oatpp::Object<Test1>>(caret);
}
}

View File

@ -28,9 +28,9 @@
#include "oatpp/json/ObjectMapper.hpp"
#include "oatpp/data/mapping/type/Object.hpp"
#include "oatpp/data/mapping/type/List.hpp"
#include "oatpp/data/mapping/type/Primitive.hpp"
#include "oatpp/data/type/Object.hpp"
#include "oatpp/data/type/List.hpp"
#include "oatpp/data/type/Primitive.hpp"
#include "oatpp/utils/Conversion.hpp"
@ -163,9 +163,9 @@ class TestAnyNested : public oatpp::DTO {
}
void DTOMapperTest::onRun(){
auto mapper = oatpp::json::ObjectMapper::createShared();
mapper->getSerializer()->getConfig()->useBeautifier = true;
oatpp::json::ObjectMapper mapper;
mapper.serializerConfig().json.useBeautifier = true;
{
auto test1 = Test::createShared();
@ -267,7 +267,7 @@ void DTOMapperTest::onRun(){
{"key11", "map_item11"}
};
auto result = mapper->writeToString(test1);
auto result = mapper.writeToString(test1);
OATPP_LOGV(TAG, "json='%s'", result->c_str())
@ -276,7 +276,7 @@ void DTOMapperTest::onRun(){
OATPP_LOGV(TAG, "...")
oatpp::utils::parser::Caret caret(result);
auto obj1 = mapper->readFromCaret<oatpp::Object<Test>>(caret);
auto obj1 = mapper.readFromCaret<oatpp::Object<Test>>(caret);
OATPP_ASSERT(obj1->field_string)
OATPP_ASSERT(obj1->field_string == test1->field_string)
@ -320,7 +320,7 @@ void DTOMapperTest::onRun(){
OATPP_ASSERT(c["key3"] == "map_item3")
}
result = mapper->writeToString(obj1);
result = mapper.writeToString(obj1);
OATPP_LOGV(TAG, "json='%s'", result->c_str())
}
@ -329,8 +329,8 @@ void DTOMapperTest::onRun(){
auto test2 = Test2::createShared();
oatpp::String result;
try {
result = mapper->writeToString(test2);
} catch(std::runtime_error& e) {
result = mapper.writeToString(test2);
} catch(std::runtime_error&) {
OATPP_LOGV(TAG, "Test2::field_string is required!")
}
OATPP_ASSERT(result == nullptr)
@ -339,8 +339,8 @@ void DTOMapperTest::onRun(){
{
auto test3 = Test3::createShared();
try {
auto result = mapper->writeToString(test3);
} catch(std::runtime_error& e) {
auto result = mapper.writeToString(test3);
} catch(std::runtime_error&) {
OATPP_ASSERT(false)
}
}
@ -351,8 +351,8 @@ void DTOMapperTest::onRun(){
test4->child = TestChild1::createShared();
oatpp::String result;
try {
result = mapper->writeToString(test4);
} catch(std::runtime_error& e) {
result = mapper.writeToString(test4);
} catch(std::runtime_error&) {
OATPP_LOGV(TAG, "TestChild1::name is required!")
}
OATPP_ASSERT(result == nullptr)
@ -363,8 +363,8 @@ void DTOMapperTest::onRun(){
test5->field_string = "string value";
test5->child = TestChild2::createShared();
try {
auto result = mapper->writeToString(test5);
} catch(std::runtime_error& e) {
auto result = mapper.writeToString(test5);
} catch(std::runtime_error&) {
OATPP_ASSERT(false)
}
}
@ -388,12 +388,12 @@ void DTOMapperTest::onRun(){
obj2->anyList->push_back(map);
auto json = mapper->writeToString(obj2);
auto json = mapper.writeToString(obj2);
OATPP_LOGV(TAG, "any json='%s'", json->c_str())
auto deserializedAny = mapper->readFromString<oatpp::Fields<oatpp::Any>>(json);
auto deserializedAny = mapper.readFromString<oatpp::Fields<oatpp::Any>>(json);
auto json2 = mapper->writeToString(deserializedAny);
auto json2 = mapper.writeToString(deserializedAny);
OATPP_LOGV(TAG, "any json='%s'", json2->c_str())
}

View File

@ -144,77 +144,77 @@ class AnyDto : public oatpp::DTO {
}
void DeserializerTest::onRun(){
oatpp::json::ObjectMapper mapper;
auto mapper = oatpp::json::ObjectMapper::createShared();
auto obj1 = mapper->readFromString<oatpp::Object<Test1>>("{}");
auto obj1 = mapper.readFromString<oatpp::Object<Test1>>("{}");
OATPP_ASSERT(obj1)
OATPP_ASSERT(!obj1->strF)
obj1 = mapper->readFromString<oatpp::Object<Test1>>(R"({"strF":"value1"})");
obj1 = mapper.readFromString<oatpp::Object<Test1>>(R"({"strF":"value1"})");
OATPP_ASSERT(obj1)
OATPP_ASSERT(obj1->strF)
OATPP_ASSERT(obj1->strF == "value1")
obj1 = mapper->readFromString<oatpp::Object<Test1>>("{\n\r\t\f\"strF\"\n\r\t\f:\n\r\t\f\"value1\"\n\r\t\f}");
obj1 = mapper.readFromString<oatpp::Object<Test1>>("{\n\r\t\f\"strF\"\n\r\t\f:\n\r\t\f\"value1\"\n\r\t\f}");
OATPP_ASSERT(obj1)
OATPP_ASSERT(obj1->strF)
OATPP_ASSERT(obj1->strF == "value1")
auto obj2 = mapper->readFromString<oatpp::Object<Test2>>("{\"int32F\": null}");
auto obj2 = mapper.readFromString<oatpp::Object<Test2>>("{\"int32F\": null}");
OATPP_ASSERT(obj2)
OATPP_ASSERT(!obj2->int32F)
obj2 = mapper->readFromString<oatpp::Object<Test2>>("{\"int32F\": 32}");
obj2 = mapper.readFromString<oatpp::Object<Test2>>("{\"int32F\": 32}");
OATPP_ASSERT(obj2)
OATPP_ASSERT(obj2->int32F == 32)
obj2 = mapper->readFromString<oatpp::Object<Test2>>("{\"int32F\": -32}");
obj2 = mapper.readFromString<oatpp::Object<Test2>>("{\"int32F\": -32}");
OATPP_ASSERT(obj2)
OATPP_ASSERT(obj2->int32F == -32)
auto obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": null}");
auto obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": null}");
OATPP_ASSERT(obj3)
OATPP_ASSERT(!obj3->float32F)
obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": 32}");
obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": 32}");
OATPP_ASSERT(obj3)
OATPP_ASSERT(fabsf(obj3->float32F - 32) < std::numeric_limits<float>::epsilon())
obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": 1.32e1}");
obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": 1.32e1}");
OATPP_ASSERT(obj3)
OATPP_ASSERT(obj3->float32F)
obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": 1.32e+1 }");
obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": 1.32e+1 }");
OATPP_ASSERT(obj3)
OATPP_ASSERT(obj3->float32F)
obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": 1.32e-1 }");
obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": 1.32e-1 }");
OATPP_ASSERT(obj3)
OATPP_ASSERT(obj3->float32F)
obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": -1.32E-1 }");
obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": -1.32E-1 }");
OATPP_ASSERT(obj3)
OATPP_ASSERT(obj3->float32F)
obj3 = mapper->readFromString<oatpp::Object<Test3>>("{\"float32F\": -1.32E1 }");
obj3 = mapper.readFromString<oatpp::Object<Test3>>("{\"float32F\": -1.32E1 }");
OATPP_ASSERT(obj3)
OATPP_ASSERT(obj3->float32F)
auto list = mapper->readFromString<oatpp::List<oatpp::Int32>>("[1, 2, 3]");
auto list = mapper.readFromString<oatpp::List<oatpp::Int32>>("[1, 2, 3]");
OATPP_ASSERT(list)
OATPP_ASSERT(list->size() == 3)
OATPP_ASSERT(list[0] == 1)
@ -223,100 +223,100 @@ void DeserializerTest::onRun(){
// Empty test
auto obj4 = mapper->readFromString<oatpp::Object<Test4>>("{\"object\": {}, \"list\": [], \"map\": {}}");
auto obj4 = mapper.readFromString<oatpp::Object<Test4>>("{\"object\": {}, \"list\": [], \"map\": {}}");
OATPP_ASSERT(obj4)
OATPP_ASSERT(obj4->object)
OATPP_ASSERT(obj4->list)
OATPP_ASSERT(obj4->list->size() == 0)
OATPP_ASSERT(obj4->map->size() == 0)
obj4 = mapper->readFromString<oatpp::Object<Test4>>("{\"object\": {\n\r\t}, \"list\": [\n\r\t], \"map\": {\n\r\t}}");
obj4 = mapper.readFromString<oatpp::Object<Test4>>("{\"object\": {\n\r\t}, \"list\": [\n\r\t], \"map\": {\n\r\t}}");
OATPP_ASSERT(obj4)
OATPP_ASSERT(obj4->object)
OATPP_ASSERT(obj4->list)
OATPP_ASSERT(obj4->list->size() == 0)
OATPP_ASSERT(obj4->map->size() == 0)
data::mapping::type::DTOWrapper<Test5> obj5;
data::type::DTOWrapper<Test5> obj5;
try {
obj5 = mapper->readFromString<oatpp::Object<Test5>>(R"({"strF":null})");
obj5 = mapper.readFromString<oatpp::Object<Test5>>(R"({"strF":null})");
} catch (std::runtime_error& e) {
OATPP_LOGD(TAG, "Test5::strF is required!")
}
OATPP_ASSERT(obj5 == nullptr)
try {
auto obj6 = mapper->readFromString<oatpp::Object<Test6>>(R"({"strF":null})");
auto obj6 = mapper.readFromString<oatpp::Object<Test6>>(R"({"strF":null})");
} catch (std::runtime_error& e) {
OATPP_ASSERT(false)
}
data::mapping::type::DTOWrapper<Test7> obj7;
data::type::DTOWrapper<Test7> obj7;
try {
obj7 = mapper->readFromString<oatpp::Object<Test7>>(R"({"strF":"value1", "child":{"name":null}})");
obj7 = mapper.readFromString<oatpp::Object<Test7>>(R"({"strF":"value1", "child":{"name":null}})");
} catch (std::runtime_error& e) {
OATPP_LOGD(TAG, "TestChild1::name is required!")
}
OATPP_ASSERT(obj7 == nullptr)
try {
auto obj8 = mapper->readFromString<oatpp::Object<Test8>>(R"({"strF":"value1", "child":{"name":null}})");
auto obj8 = mapper.readFromString<oatpp::Object<Test8>>(R"({"strF":"value1", "child":{"name":null}})");
} catch (std::runtime_error& e) {
OATPP_ASSERT(false)
}
OATPP_LOGD(TAG, "Any: String")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":"my_string"})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":"my_string"})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == String::Class::getType())
OATPP_ASSERT(dto->any.retrieve<String>() == "my_string")
}
OATPP_LOGD(TAG, "Any: Boolean")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":false})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":false})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == Boolean::Class::getType())
OATPP_ASSERT(dto->any.retrieve<Boolean>() == false)
}
OATPP_LOGD(TAG, "Any: Negative Float")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":-1.23456789,"another":1.1})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":-1.23456789,"another":1.1})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == Float64::Class::getType())
OATPP_ASSERT(fabs(dto->any.retrieve<Float64>() - -1.23456789) < std::numeric_limits<double>::epsilon())
}
OATPP_LOGD(TAG, "Any: Positive Float")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":1.23456789,"another":1.1})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":1.23456789,"another":1.1})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == Float64::Class::getType())
OATPP_ASSERT(fabs(dto->any.retrieve<Float64>() - 1.23456789) < std::numeric_limits<double>::epsilon())
}
OATPP_LOGD(TAG, "Any: Negative exponential Float")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":-1.2345e30,"another":1.1})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":-1.2345e30,"another":1.1})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == Float64::Class::getType())
OATPP_ASSERT(fabs(dto->any.retrieve<Float64>() - -1.2345e30) < std::numeric_limits<double>::epsilon())
}
OATPP_LOGD(TAG, "Any: Positive exponential Float")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":1.2345e30,"another":1.1})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":1.2345e30,"another":1.1})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == Float64::Class::getType())
OATPP_ASSERT(fabs(dto->any.retrieve<Float64>() - 1.2345e30) < std::numeric_limits<double>::epsilon())
}
OATPP_LOGD(TAG, "Any: Unsigned Integer")
OATPP_LOGD(TAG, "Any: Big Integer")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":12345678901234567890,"another":1.1})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":9223372036854775807,"another":1.1})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == UInt64::Class::getType())
OATPP_ASSERT(dto->any.retrieve<UInt64>() == 12345678901234567890u)
OATPP_ASSERT(dto->any.getStoredType() == Int64::Class::getType())
OATPP_ASSERT(dto->any.retrieve<Int64>() == 9223372036854775807)
}
OATPP_LOGD(TAG, "Any: Signed Integer")
{
auto dto = mapper->readFromString<oatpp::Object<AnyDto>>(R"({"any":-1234567890,"another":1.1})");
auto dto = mapper.readFromString<oatpp::Object<AnyDto>>(R"({"any":-1234567890,"another":1.1})");
OATPP_ASSERT(dto)
OATPP_ASSERT(dto->any.getStoredType() == Int64::Class::getType())
OATPP_ASSERT(dto->any.retrieve<Int64>() == -1234567890)

View File

@ -82,8 +82,8 @@ void EnumTest::onRun() {
oatpp::Fields<oatpp::Enum<Enum1>::AsString::NotNull> map = {{"enum", nullptr}};
try {
auto json = mapper.writeToString(map);
} catch (const std::runtime_error& e) {
OATPP_LOGD(TAG, "error - %s", e.what())
} catch (const data::mapping::MappingError& e) {
OATPP_LOGD(TAG, "error - '%s'\ntrace:\n%s", e.what(), e.errorStack().stacktrace()->c_str())
error = true;
}
OATPP_ASSERT(error == true)
@ -114,8 +114,8 @@ void EnumTest::onRun() {
oatpp::Fields<oatpp::Enum<Enum1>::AsNumber::NotNull> map = {{"enum", nullptr}};
try {
auto json = mapper.writeToString(map);
} catch (const std::runtime_error& e) {
OATPP_LOGD(TAG, "error - %s", e.what())
} catch (const data::mapping::MappingError& e) {
OATPP_LOGD(TAG, "error - '%s'\ntrace:\n%s", e.what(), e.errorStack().stacktrace()->c_str())
error = true;
}
OATPP_ASSERT(error == true)
@ -144,8 +144,8 @@ void EnumTest::onRun() {
oatpp::String json = "{\"enum\":null}";
try {
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsString::NotNull>>(json);
} catch (const oatpp::utils::parser::ParsingError& e) {
OATPP_LOGD(TAG, "error - %s", e.what())
} catch (const data::mapping::MappingError& e) {
OATPP_LOGD(TAG, "error - '%s'\ntrace:\n%s", e.what(), e.errorStack().stacktrace()->c_str())
error = true;
}
OATPP_ASSERT(error == true)
@ -174,8 +174,8 @@ void EnumTest::onRun() {
oatpp::String json = "{\"enum\":null}";
try {
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsNumber::NotNull>>(json);
} catch (const oatpp::utils::parser::ParsingError& e) {
OATPP_LOGD(TAG, "error - %s", e.what())
} catch (const data::mapping::MappingError& e) {
OATPP_LOGD(TAG, "error - '%s'\ntrace:\n%s", e.what(), e.errorStack().stacktrace()->c_str())
error = true;
}
OATPP_ASSERT(error == true)

View File

@ -92,7 +92,7 @@ public:
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper)([] {
return oatpp::json::ObjectMapper::createShared();
return std::make_shared<oatpp::json::ObjectMapper>();
}());
};
@ -153,7 +153,7 @@ void ClientRetryTest::onRun() {
TestClientComponent component(m_port);
auto objectMapper = oatpp::json::ObjectMapper::createShared();
auto objectMapper = std::make_shared<oatpp::json::ObjectMapper>();
auto controller = app::Controller::createShared(objectMapper);
OATPP_COMPONENT(std::shared_ptr<oatpp::network::ClientConnectionProvider>, connectionProvider);

View File

@ -95,7 +95,7 @@ public:
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::data::mapping::ObjectMapper>, objectMapper)([] {
return oatpp::json::ObjectMapper::createShared();
return std::make_shared<oatpp::json::ObjectMapper>();
}());
OATPP_CREATE_COMPONENT(std::shared_ptr<oatpp::network::ClientConnectionProvider>, clientConnectionProvider)([this] {

Some files were not shown because too many files have changed in this diff Show More