mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2025-01-05 17:42:23 +08:00
commit
e4d0776584
12
README.md
12
README.md
@ -50,7 +50,7 @@ For more info see [Api Controller](https://oatpp.io/docs/components/api-controll
|
||||
```cpp
|
||||
ENDPOINT("PUT", "/users/{userId}", putUser,
|
||||
PATH(Int64, userId),
|
||||
BODY_DTO(dto::UserDto::ObjectWrapper, userDto))
|
||||
BODY_DTO(dto::UserDto, userDto))
|
||||
{
|
||||
userDto->id = userId;
|
||||
return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto));
|
||||
@ -65,7 +65,7 @@ For more info see [Api Controller / CORS](https://oatpp.io/docs/components/api-c
|
||||
ADD_CORS(putUser)
|
||||
ENDPOINT("PUT", "/users/{userId}", putUser,
|
||||
PATH(Int64, userId),
|
||||
BODY_DTO(dto::UserDto::ObjectWrapper, userDto))
|
||||
BODY_DTO(dto::UserDto, userDto))
|
||||
{
|
||||
userDto->id = userId;
|
||||
return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto));
|
||||
@ -82,7 +82,7 @@ using namespace oatpp::web::server::handler;
|
||||
ENDPOINT("PUT", "/users/{userId}", putUser,
|
||||
AUTHORIZATION(std::shared_ptr<DefaultBasicAuthorizationObject>, authObject),
|
||||
PATH(Int64, userId),
|
||||
BODY_DTO(dto::UserDto::ObjectWrapper, userDto))
|
||||
BODY_DTO(dto::UserDto, userDto))
|
||||
{
|
||||
OATPP_ASSERT_HTTP(authObject->userId == "Ivan" && authObject->password == "admin", Status::CODE_401, "Unauthorized");
|
||||
userDto->id = userId;
|
||||
@ -100,15 +100,15 @@ For more info see [Endpoint Annotation And API Documentation](https://oatpp.io/d
|
||||
ENDPOINT_INFO(putUser) {
|
||||
// general
|
||||
info->summary = "Update User by userId";
|
||||
info->addConsumes<dto::UserDto::ObjectWrapper>("application/json");
|
||||
info->addResponse<dto::UserDto::ObjectWrapper>(Status::CODE_200, "application/json");
|
||||
info->addConsumes<dto::UserDto>("application/json");
|
||||
info->addResponse<dto::UserDto>(Status::CODE_200, "application/json");
|
||||
info->addResponse<String>(Status::CODE_404, "text/plain");
|
||||
// params specific
|
||||
info->pathParams["userId"].description = "User Identifier";
|
||||
}
|
||||
ENDPOINT("PUT", "/users/{userId}", putUser,
|
||||
PATH(Int64, userId),
|
||||
BODY_DTO(dto::UserDto::ObjectWrapper, userDto))
|
||||
BODY_DTO(dto::UserDto, userDto))
|
||||
{
|
||||
userDto->id = userId;
|
||||
return createDtoResponse(Status::CODE_200, m_database->updateUser(userDto));
|
||||
|
322
changelog/1.1.0.md
Normal file
322
changelog/1.1.0.md
Normal file
@ -0,0 +1,322 @@
|
||||
# Oat++ 1.1.0
|
||||
|
||||
Oat++ `1.1.0` is introducing breaking changes.
|
||||
Please read carefully to prepare for migration.
|
||||
|
||||
Feel free to ask questions - [Chat on Gitter](https://gitter.im/oatpp-framework/Lobby)
|
||||
|
||||
Contents:
|
||||
- [No more explicit ObjectWrapper](#no-more-explicit-objectwrapper)
|
||||
- [Object-Mapping Simplified Primitives](#object-mapping-simplified-primitives)
|
||||
- [Object-Mapping std Collections](#object-mapping-std-collections)
|
||||
- [Type oatpp::Any](#type-oatppany)
|
||||
- [Type oatpp::Enum](#object-mapping-enum)
|
||||
- [DTO - Hashcode & Equals](#dto-hashcode-and-equals)
|
||||
- [DTO - Fields Annotation](#dto-fields-annotation)
|
||||
|
||||
## No more explicit ObjectWrapper
|
||||
|
||||
Do not explicitly write `ObjectWrapper`
|
||||
|
||||
DTO:
|
||||
|
||||
```cpp
|
||||
class MyDto : oatpp::Object {
|
||||
|
||||
DTO_INIT(MyDto, Object)
|
||||
|
||||
DTO_FIELD(MyDto, nested);
|
||||
DTO_FIELD(List<Any>, listOfAny);
|
||||
DTO_FIELD(Fields<List<String>>, mapOfLists);
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
ApiController:
|
||||
|
||||
```cpp
|
||||
ENDPOINT("POST", "body-dto", postWithBody,
|
||||
BODY_DTO(MyDto, body)) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Object-Mapping Simplified Primitives
|
||||
|
||||
No more `<primitive>->getValue()`.
|
||||
|
||||
```cpp
|
||||
oatpp::Int32 objV = 32;
|
||||
v_int32 v = objV; // You may check for nullptr before doing this
|
||||
|
||||
bool equals = v == objV; // <--- NO NEED to check for nullptr here
|
||||
bool isNull = objV == nullptr;
|
||||
bool isNull = !objV;
|
||||
```
|
||||
|
||||
## Object-Mapping std Collections
|
||||
|
||||
Now `oatpp::<mapping-enabled-collections>` are based on `std::<collections>`
|
||||
|
||||
Example:
|
||||
|
||||
```cpp
|
||||
oatpp::Vector<oatpp::String> vector = oatpp::Vector<oatpp::String>::createShared();
|
||||
oatpp::List<oatpp::String> list = oatpp::List<oatpp::String>::createShared();
|
||||
oatpp::UnorderedSet<oatpp::String> set = oatpp::UnorderedSet<oatpp::String>::createShared();
|
||||
oatpp::Fields<oatpp::String> pairList= oatpp::Fields<oatpp::String>::createShared();
|
||||
oatpp::UnorderedFields<oatpp::String> hashMap = oatpp::UnorderedFields<oatpp::String>::createShared();
|
||||
|
||||
oatpp::Vector<oatpp::String> vector = {"a", "b", "c"};
|
||||
oatpp::List<oatpp::String> list = {"a", "b", "c"};
|
||||
oatpp::UnorderedSet<oatpp::String> set = {"a", "b", "c"};
|
||||
oatpp::Fields<oatpp::String> pairList = {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}};
|
||||
oatpp::UnorderedFields<oatpp::String> hashMap = {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}};
|
||||
|
||||
vector[0] = "z"; // <--- Complexity = O(1);
|
||||
vector->push_back("www");
|
||||
|
||||
list[0] = "z"; // <--- Complexity = O(n);
|
||||
list->push_back("www");
|
||||
|
||||
bool contains = set["b"]; // <--- Complexity = O(1);
|
||||
set->insert("z")
|
||||
|
||||
pairList["k1"] = "z"; // <--- Complexity = O(n);
|
||||
pairList->push_back({"key_z", "z"});
|
||||
|
||||
hashMap["k1"] = "z" // <--- Complexity = O(1);
|
||||
hashMap->insert({"key_z", "z"});
|
||||
|
||||
for(auto& item : *vector) {
|
||||
...
|
||||
}
|
||||
|
||||
for(auto& item : *list) {
|
||||
...
|
||||
}
|
||||
|
||||
for(auto& item : *set) {
|
||||
...
|
||||
}
|
||||
|
||||
for(auto& pair : *pairList) {
|
||||
...
|
||||
}
|
||||
|
||||
for(auto& pair : *hashMap) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Type oatpp::Any
|
||||
|
||||
The new Type Introduced - `oatpp::Any`.
|
||||
|
||||
Now it's possible to do like this:
|
||||
|
||||
```cpp
|
||||
class MyDto : public oatpp::Object {
|
||||
|
||||
DTO_INIT(MyDto, Object)
|
||||
|
||||
DTO_FIELD(Any, any); // Put any oatpp::<Type> here
|
||||
DTO_FIELD(List<Any>, listOfAny)
|
||||
DTO_FIELD(Fields<Any>, mapOfAny);
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
### JSON Serializer
|
||||
|
||||
Will serialize Any depending on the value type it stores.
|
||||
|
||||
### JSON Deserializer
|
||||
|
||||
Will try to guess the type of the `Any`.
|
||||
Currently, `Any` is deserialized as follows:
|
||||
|
||||
- JSON objects are deserialized to `Any` holding `oatpp::Fields<Any>`.
|
||||
- JSON lists are deserialized to `Any` holding `oatpp::List<Any>`.
|
||||
- JSON `null` is deserialized to `Any` holding `nullptr`.
|
||||
- JSON `true`/`false` is deserialized to `Any` holding `oatpp::Boolean`.
|
||||
- JSON `number` is deserialized to `Any` holding `oatpp::Float64`.
|
||||
|
||||
### Example
|
||||
|
||||
```cpp
|
||||
oatpp::Fields<oatpp::Any> map = {
|
||||
{"title", oatpp::String("Hello Any!")},
|
||||
{"listOfAny",
|
||||
oatpp::List<oatpp::Any>({
|
||||
oatpp::Int32(32),
|
||||
oatpp::Float32(0.32),
|
||||
oatpp::Boolean(true)
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
auto json = mapper->writeToString(map);
|
||||
```
|
||||
|
||||
**Output:**
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "Hello Any!",
|
||||
"listOfAny": [
|
||||
32,
|
||||
0.3199999928474426,
|
||||
true
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Object-Mapping Enum
|
||||
|
||||
Enum is added to DTO codegen.
|
||||
|
||||
### Declaration
|
||||
|
||||
```cpp
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
ENUM(Enum1, v_int32, // <-- type is mandatory
|
||||
VALUE(V_1, 1), // <-- integral value is mandatory
|
||||
VALUE(V_2, 2, "name-2"),
|
||||
VALUE(V_3, 3, "name-3", "description_3")
|
||||
)
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
```
|
||||
|
||||
This will generate:
|
||||
|
||||
```cpp
|
||||
enum class Enum1 : v_int32 {
|
||||
V_1 = 1,
|
||||
V_2 = 2,
|
||||
V_3 = 3
|
||||
}
|
||||
|
||||
... // PLUS Meta here
|
||||
```
|
||||
|
||||
Current limitation - `ENUM` can not be declared nested in the class :(.
|
||||
This may be fixed later.
|
||||
|
||||
### Usage
|
||||
|
||||
#### DTO
|
||||
|
||||
```cpp
|
||||
ENUM(MyEnum, v_int32,
|
||||
VALUE(V1, 10, "enum1-v1"),
|
||||
VALUE(V2, 20, "enum1-v2"),
|
||||
VALUE(V3, 30, "enum1-v3")
|
||||
);
|
||||
|
||||
class MyDto : public oatpp::Object {
|
||||
|
||||
DTO_INIT(MyDto, Object)
|
||||
|
||||
DTO_FIELD(Enum<MyEnum>, enum1); // Default interpretation - AsString
|
||||
DTO_FIELD(Enum<MyEnum>::NotNull, enum2); // NOT_NULL constraint for Ser/De
|
||||
|
||||
DTO_FIELD(Enum<MyEnum>::AsString, enum3); // Ser/De as string name
|
||||
DTO_FIELD(Enum<MyEnum>::AsNumber, enum4); // Ser/De as a corresponding integral value
|
||||
|
||||
DTO_FIELD(Enum<MyEnum>::AsString::NotNull, enum5);
|
||||
DTO_FIELD(Enum<MyEnum>::AsNumber::NotNull, enum6);
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
#### ApiController
|
||||
|
||||
```cpp
|
||||
ENDPOINT("GET", "enum/as-string", testEnumString,
|
||||
HEADER(Enum<AllowedHeaderValues>::AsString, enumValue, "X-MyEnum"))
|
||||
{
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "enum/as-number", testEnumNumber,
|
||||
HEADER(Enum<AllowedHeaderValues>::AsNumber, enumValue, "X-MyEnum"))
|
||||
{
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
}
|
||||
```
|
||||
|
||||
#### ApiClient
|
||||
|
||||
```cpp
|
||||
API_CALL("GET", "enum/as-string", getWithEnumHeaderAsString, HEADER(Enum<AllowedHeaderValues>::AsString, enumValue, "X-MyEnum"))
|
||||
API_CALL("GET", "enum/as-number", getWithEnumHeaderAsNumber, HEADER(Enum<AllowedHeaderValues>::AsNumber, enumValue, "X-MyEnum"))
|
||||
```
|
||||
|
||||
### Meta functions
|
||||
|
||||
```cpp
|
||||
{
|
||||
auto entry = oatpp::Enum<MyEnum>::getEntryByName("<name>");
|
||||
auto entry = oatpp::Enum<MyEnum>::getEntryByValue(MyEnum::VALUE);
|
||||
auto entry = oatpp::Enum<MyEnum>::getEntryByUnderlyingValue(123);
|
||||
auto entry = oatpp::Enum<MyEnum>::getEntryByIndex(0);
|
||||
...
|
||||
OATPP_LOGD("Entry", "%d, %s, %d, %d, %s", entry.index, entry.name, entry.value, entry.description);
|
||||
}
|
||||
|
||||
{
|
||||
const auto& entries = oatpp::Enum<MyEnum>::getEntries();
|
||||
for(const auto& e : entries) {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## DTO Hashcode and Equals
|
||||
|
||||
Now DTOs can be used as a Key in `unordered_map` and `unordered_set`.
|
||||
The convenience `DTO_HC_EQ` (DTO_HASHCODE_AND_EQUALS) macro has been added.
|
||||
|
||||
```cpp
|
||||
class User : public oatpp::Object {
|
||||
|
||||
DTO_INIT(User, Object)
|
||||
|
||||
DTO_FIELD(String, firstName);
|
||||
DTO_FIELD(String, lastName);
|
||||
|
||||
DTO_HC_EQ(firstName, lastName) // List key fields that count in std::hash and "==","!=" operators.
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
The `DTO_HC_EQ` macro works taking into account the `DTO_HC_EQ` declared in the parent DTO class.
|
||||
|
||||
If no `DTO_HC_EQ` is declared in none of the DTO's parent classes the default behavior is:
|
||||
- `std::hash` - is `v_uint64` representation of object address.
|
||||
- operators `==` and `!=` - is comparison of object addresses.
|
||||
|
||||
## DTO Fields Annotation
|
||||
|
||||
Now it's possible to add a description for DTO fields, which will be automatically
|
||||
displayed in swagger-UI.
|
||||
|
||||
```cpp
|
||||
class MyDto : public oatpp::Object {
|
||||
|
||||
DTO_INIT(MyDto, Object)
|
||||
|
||||
DTO_FIELD_INFO(id) {
|
||||
info->description = "identifier";
|
||||
}
|
||||
DTO_FIELD(String, id);
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
*Note: The `description` is currently the only info you can add to the DTO field
|
||||
(This may be extended later). In order to provide the list of possible values - use the
|
||||
new Enum feature - [Type oatpp::Enum](#object-mapping-enum).*
|
@ -11,12 +11,16 @@ add_library(oatpp
|
||||
oatpp/codegen/api_controller/auth_undef.hpp
|
||||
oatpp/codegen/api_controller/cors_define.hpp
|
||||
oatpp/codegen/api_controller/cors_undef.hpp
|
||||
oatpp/codegen/codegen_define_ApiClient_.hpp
|
||||
oatpp/codegen/codegen_define_ApiController_.hpp
|
||||
oatpp/codegen/codegen_define_DTO_.hpp
|
||||
oatpp/codegen/codegen_undef_ApiClient_.hpp
|
||||
oatpp/codegen/codegen_undef_ApiController_.hpp
|
||||
oatpp/codegen/codegen_undef_DTO_.hpp
|
||||
oatpp/codegen/ApiController_define.hpp
|
||||
oatpp/codegen/ApiController_undef.hpp
|
||||
oatpp/codegen/ApiClient_define.hpp
|
||||
oatpp/codegen/ApiClient_undef.hpp
|
||||
oatpp/codegen/dto/base_define.hpp
|
||||
oatpp/codegen/dto/base_undef.hpp
|
||||
oatpp/codegen/dto/enum_define.hpp
|
||||
oatpp/codegen/dto/enum_undef.hpp
|
||||
oatpp/codegen/DTO_define.hpp
|
||||
oatpp/codegen/DTO_undef.hpp
|
||||
oatpp/core/Types.hpp
|
||||
oatpp/core/async/Coroutine.cpp
|
||||
oatpp/core/async/Coroutine.hpp
|
||||
@ -74,16 +78,26 @@ add_library(oatpp
|
||||
oatpp/core/data/buffer/Processor.hpp
|
||||
oatpp/core/data/mapping/ObjectMapper.cpp
|
||||
oatpp/core/data/mapping/ObjectMapper.hpp
|
||||
oatpp/core/data/mapping/type/Any.cpp
|
||||
oatpp/core/data/mapping/type/Any.hpp
|
||||
oatpp/core/data/mapping/type/Enum.cpp
|
||||
oatpp/core/data/mapping/type/Enum.hpp
|
||||
oatpp/core/data/mapping/type/List.cpp
|
||||
oatpp/core/data/mapping/type/List.hpp
|
||||
oatpp/core/data/mapping/type/ListMap.cpp
|
||||
oatpp/core/data/mapping/type/ListMap.hpp
|
||||
oatpp/core/data/mapping/type/PairList.cpp
|
||||
oatpp/core/data/mapping/type/PairList.hpp
|
||||
oatpp/core/data/mapping/type/Object.cpp
|
||||
oatpp/core/data/mapping/type/Object.hpp
|
||||
oatpp/core/data/mapping/type/Primitive.cpp
|
||||
oatpp/core/data/mapping/type/Primitive.hpp
|
||||
oatpp/core/data/mapping/type/Type.cpp
|
||||
oatpp/core/data/mapping/type/Type.hpp
|
||||
oatpp/core/data/mapping/type/UnorderedMap.cpp
|
||||
oatpp/core/data/mapping/type/UnorderedMap.hpp
|
||||
oatpp/core/data/mapping/type/UnorderedSet.cpp
|
||||
oatpp/core/data/mapping/type/UnorderedSet.hpp
|
||||
oatpp/core/data/mapping/type/Vector.cpp
|
||||
oatpp/core/data/mapping/type/Vector.hpp
|
||||
oatpp/core/data/share/LazyStringMap.hpp
|
||||
oatpp/core/data/share/MemoryLabel.cpp
|
||||
oatpp/core/data/share/MemoryLabel.hpp
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_PARAM_MACRO(MACRO, TYPE, PARAM_LIST) MACRO(TYPE, PARAM_LIST)
|
||||
#define OATPP_MACRO_API_CLIENT_PARAM_TYPE(MACRO, TYPE, PARAM_LIST) TYPE
|
||||
#define OATPP_MACRO_API_CLIENT_PARAM_TYPE(MACRO, TYPE, PARAM_LIST) const TYPE&
|
||||
#define OATPP_MACRO_API_CLIENT_PARAM_NAME(MACRO, TYPE, PARAM_LIST) OATPP_MACRO_FIRSTARG PARAM_LIST
|
||||
#define OATPP_MACRO_API_CLIENT_PARAM_TYPE_STR(MACRO, TYPE, PARAM_LIST) #TYPE
|
||||
#define OATPP_MACRO_API_CLIENT_PARAM_NAME_STR(MACRO, TYPE, PARAM_LIST) OATPP_MACRO_FIRSTARG_STR PARAM_LIST
|
||||
@ -56,14 +56,14 @@
|
||||
#define PATH(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_PATH, TYPE, (__VA_ARGS__))
|
||||
#define QUERY(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_QUERY, TYPE, (__VA_ARGS__))
|
||||
#define BODY(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY, TYPE, (__VA_ARGS__))
|
||||
#define BODY_DTO(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY_DTO, TYPE, (__VA_ARGS__))
|
||||
#define BODY_DTO(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY_DTO, TYPE::__Wrapper, (__VA_ARGS__))
|
||||
#define BODY_STRING(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_BODY_STRING, TYPE, (__VA_ARGS__))
|
||||
#define AUTHORIZATION(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_AUTHORIZATION, TYPE, (__VA_ARGS__))
|
||||
#define AUTHORIZATION_BASIC(TYPE, ...) OATPP_MACRO_API_CLIENT_PARAM(OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC, TYPE, (__VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(MACRO, TYPE, ...) \
|
||||
#define OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(MACRO, TYPE, ...) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (TYPE, __VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -89,35 +89,35 @@ public: \
|
||||
// HEADER MACRO
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_HEADER_1(TYPE, NAME) \
|
||||
__headers->put(#NAME, convertParameterToString(#TYPE, NAME));
|
||||
__headers->put(#NAME, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_HEADER_2(TYPE, NAME, QUALIFIER) \
|
||||
__headers->put(QUALIFIER, convertParameterToString(#TYPE, NAME));
|
||||
__headers->put(QUALIFIER, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_HEADER(TYPE, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_HEADER_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_HEADER_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
|
||||
// PATH MACRO
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_PATH_1(TYPE, NAME) \
|
||||
__pathParams->put(#NAME, convertParameterToString(#TYPE, NAME));
|
||||
__pathParams->put(#NAME, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_PATH_2(TYPE, NAME, QUALIFIER) \
|
||||
__pathParams->put(QUALIFIER, convertParameterToString(#TYPE, NAME));
|
||||
__pathParams->put(QUALIFIER, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_PATH(TYPE, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_PATH_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_PATH_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
|
||||
// QUERY MACRO
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_QUERY_1(TYPE, NAME) \
|
||||
__queryParams->put(#NAME, convertParameterToString(#TYPE, NAME));
|
||||
__queryParams->put(#NAME, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_QUERY_2(TYPE, NAME, QUALIFIER) \
|
||||
__queryParams->put(QUALIFIER, convertParameterToString(#TYPE, NAME));
|
||||
__queryParams->put(QUALIFIER, ApiClient::TypeInterpretation<TYPE>::toString(#TYPE, NAME));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_QUERY(TYPE, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_QUERY_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_QUERY_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
|
||||
// BODY MACRO
|
||||
|
||||
@ -143,7 +143,7 @@ __body = oatpp::web::protocol::http::outgoing::BufferBody::createShared(OATPP_MA
|
||||
__headers->put("Authorization", String(SCHEME " ") + String(TOKEN));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_AUTHORIZATION(TYPE, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
|
||||
// AUTHORIZATION_BASIC MACRO
|
||||
|
||||
@ -151,7 +151,7 @@ OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_,
|
||||
__headers->put("Authorization", String("Basic ") + oatpp::encoding::Base64::encode(TOKEN));
|
||||
|
||||
#define OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC(TYPE, PARAM_LIST) \
|
||||
OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
OATPP_MACRO_API_CLIENT_MACRO_SELECTOR(OATPP_MACRO_API_CLIENT_AUTHORIZATION_BASIC_, TYPE, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
|
||||
// FOR EACH
|
||||
|
@ -59,7 +59,7 @@
|
||||
#undef AUTHORIZATION_BASIC
|
||||
//
|
||||
|
||||
#undef OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR
|
||||
#undef OATPP_MACRO_API_CLIENT_MACRO_SELECTOR
|
||||
|
||||
// INIT
|
||||
|
49
src/oatpp/codegen/DTO_define.hpp
Normal file
49
src/oatpp/codegen/DTO_define.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/**[info]
|
||||
* This file contains "defines" for DTO code generating macro. <br>
|
||||
* Usage:<br>
|
||||
*
|
||||
* ```cpp
|
||||
* #include OATPP_CODEGEN_BEGIN(DTO)
|
||||
* ...
|
||||
* // Generated Endpoints.
|
||||
* ...
|
||||
* #include OATPP_CODEGEN_END(DTO)
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* *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>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
#include "oatpp/core/macro/basic.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
#include "./dto/base_define.hpp"
|
||||
#include "./dto/enum_define.hpp"
|
@ -42,10 +42,5 @@
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
#undef DTO_INIT
|
||||
|
||||
// Fields
|
||||
|
||||
#undef OATPP_MACRO_DTO_FIELD_1
|
||||
#undef OATPP_MACRO_DTO_FIELD_2
|
||||
#undef DTO_FIELD
|
||||
#include "./dto/base_undef.hpp"
|
||||
#include "./dto/enum_undef.hpp"
|
@ -24,7 +24,7 @@
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_MACRO(MACRO, INFO, TYPE, PARAM_LIST) MACRO(TYPE, PARAM_LIST)
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_INFO(MACRO, INFO, TYPE, PARAM_LIST) INFO(TYPE, PARAM_LIST)
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_TYPE(MACRO, INFO, TYPE, PARAM_LIST) TYPE
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_TYPE(MACRO, INFO, TYPE, PARAM_LIST) const TYPE&
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_NAME(MACRO, INFO, TYPE, PARAM_LIST) OATPP_MACRO_FIRSTARG PARAM_LIST
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_TYPE_STR(MACRO, INFO, TYPE, PARAM_LIST) #TYPE
|
||||
#define OATPP_MACRO_API_CONTROLLER_PARAM_NAME_STR(MACRO, INFO, TYPE, PARAM_LIST) OATPP_MACRO_FIRSTARG_STR PARAM_LIST
|
||||
@ -49,7 +49,7 @@ OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_QUERY, OATPP_MACRO_A
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_BODY_STRING, OATPP_MACRO_API_CONTROLLER_BODY_STRING_INFO, TYPE, (__VA_ARGS__))
|
||||
|
||||
#define BODY_DTO(TYPE, ...) \
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_BODY_DTO, OATPP_MACRO_API_CONTROLLER_BODY_DTO_INFO, TYPE, (__VA_ARGS__))
|
||||
OATPP_MACRO_API_CONTROLLER_PARAM(OATPP_MACRO_API_CONTROLLER_BODY_DTO, OATPP_MACRO_API_CONTROLLER_BODY_DTO_INFO, TYPE::__Wrapper, (__VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -61,7 +61,7 @@ OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (TYPE, __VA_
|
||||
// REQUEST MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_REQUEST(TYPE, PARAM_LIST) \
|
||||
TYPE OATPP_MACRO_FIRSTARG PARAM_LIST = __request;
|
||||
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request;
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_REQUEST_INFO(TYPE, PARAM_LIST)
|
||||
|
||||
@ -69,24 +69,24 @@ TYPE OATPP_MACRO_FIRSTARG PARAM_LIST = __request;
|
||||
// HEADER MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_HEADER_1(TYPE, NAME) \
|
||||
auto __param_str_val_##NAME = __request->getHeader(#NAME); \
|
||||
const auto& __param_str_val_##NAME = __request->getHeader(#NAME); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Missing HEADER parameter '" #NAME "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = parseParameterFromString<TYPE>(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Invalid HEADER parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_HEADER_2(TYPE, NAME, QUALIFIER) \
|
||||
auto __param_str_val_##NAME = __request->getHeader(QUALIFIER); \
|
||||
const auto& __param_str_val_##NAME = __request->getHeader(QUALIFIER); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Missing HEADER parameter '") + QUALIFIER + "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = parseParameterFromString<TYPE>(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Invalid HEADER parameter '") + \
|
||||
@ -112,24 +112,24 @@ OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CONTROLLER_HEADER_INFO
|
||||
// PATH MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_PATH_1(TYPE, NAME) \
|
||||
auto __param_str_val_##NAME = __request->getPathVariable(#NAME); \
|
||||
const auto& __param_str_val_##NAME = __request->getPathVariable(#NAME); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Missing PATH parameter '" #NAME "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = parseParameterFromString<TYPE>(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Invalid PATH parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_PATH_2(TYPE, NAME, QUALIFIER) \
|
||||
auto __param_str_val_##NAME = __request->getPathVariable(QUALIFIER); \
|
||||
const auto& __param_str_val_##NAME = __request->getPathVariable(QUALIFIER); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Missing PATH parameter '") + QUALIFIER + "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = parseParameterFromString<TYPE>(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
const auto NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Invalid PATH parameter '") + \
|
||||
@ -154,31 +154,31 @@ OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CONTROLLER_PATH_INFO_,
|
||||
// QUERIES MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERIES(TYPE, PARAM_LIST) \
|
||||
TYPE OATPP_MACRO_FIRSTARG PARAM_LIST = __request->getQueryParameters();
|
||||
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request->getQueryParameters();
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERIES_INFO(TYPE, PARAM_LIST)
|
||||
|
||||
// QUERY MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_1(TYPE, NAME) \
|
||||
auto __param_str_val_##NAME = __request->getQueryParameter(#NAME); \
|
||||
const auto& __param_str_val_##NAME = __request->getQueryParameter(#NAME); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Missing QUERY parameter '" #NAME "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = parseParameterFromString<TYPE>(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, "Invalid QUERY parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_2(TYPE, NAME, QUALIFIER) \
|
||||
auto __param_str_val_##NAME = __request->getQueryParameter(QUALIFIER); \
|
||||
const auto& __param_str_val_##NAME = __request->getQueryParameter(QUALIFIER); \
|
||||
if(!__param_str_val_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Missing QUERY parameter '") + QUALIFIER + "'"); \
|
||||
} \
|
||||
bool __param_validation_check_##NAME; \
|
||||
TYPE NAME = parseParameterFromString<TYPE>(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||
if(!__param_validation_check_##NAME){ \
|
||||
return ApiController::handleError(Status::CODE_400, \
|
||||
oatpp::String("Invalid QUERY parameter '") + \
|
||||
@ -203,7 +203,7 @@ OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CONTROLLER_QUERY_INFO_
|
||||
// BODY_STRING MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_BODY_STRING(TYPE, PARAM_LIST) \
|
||||
TYPE OATPP_MACRO_FIRSTARG PARAM_LIST = __request->readBodyToString();
|
||||
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request->readBodyToString();
|
||||
|
||||
// __INFO
|
||||
|
||||
@ -214,8 +214,8 @@ info->body.type = oatpp::data::mapping::type::__class::String::getType();
|
||||
// BODY_DTO MACRO // ------------------------------------------------------
|
||||
|
||||
#define OATPP_MACRO_API_CONTROLLER_BODY_DTO(TYPE, PARAM_LIST) \
|
||||
TYPE OATPP_MACRO_FIRSTARG PARAM_LIST; \
|
||||
__request->readBodyToDto(OATPP_MACRO_FIRSTARG PARAM_LIST, getDefaultObjectMapper().get()); \
|
||||
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = \
|
||||
__request->readBodyToDto<TYPE>(getDefaultObjectMapper().get()); \
|
||||
if(!OATPP_MACRO_FIRSTARG PARAM_LIST) { \
|
||||
return ApiController::handleError(Status::CODE_400, "Missing valid body parameter '" OATPP_MACRO_FIRSTARG_STR PARAM_LIST "'"); \
|
||||
}
|
||||
|
@ -1,144 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/**[info]
|
||||
* This file contains "defines" for DTO code generating macro. <br>
|
||||
* Usage:<br>
|
||||
*
|
||||
* ```cpp
|
||||
* #include OATPP_CODEGEN_BEGIN(DTO)
|
||||
* ...
|
||||
* // Generated Endpoints.
|
||||
* ...
|
||||
* #include OATPP_CODEGEN_END(DTO)
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* *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>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
#include "oatpp/core/macro/basic.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
// Defaults
|
||||
|
||||
/**
|
||||
* Codegen macoro to be used in classes extending &id:oatpp::data::mapping::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`.
|
||||
*/
|
||||
#define DTO_INIT(TYPE_NAME, TYPE_EXTEND) \
|
||||
public: \
|
||||
typedef TYPE_NAME Z__CLASS; \
|
||||
typedef TYPE_EXTEND Z__CLASS_EXTENDED; \
|
||||
typedef oatpp::data::mapping::type::ObjectWrapper<Z__CLASS, oatpp::data::mapping::type::__class::Object<Z__CLASS>> ObjectWrapper; \
|
||||
public: \
|
||||
OBJECT_POOL(DTO_OBJECT_POOL_##TYPE_NAME, TYPE_NAME, 32) \
|
||||
SHARED_OBJECT_POOL(SHARED_DTO_OBJECT_POOL_##TYPE_NAME, TYPE_NAME, 32) \
|
||||
protected: \
|
||||
oatpp::data::mapping::type::Type::Properties* Z__CLASS_INIT_FIELDS(oatpp::data::mapping::type::Type::Properties* properties, \
|
||||
oatpp::data::mapping::type::Type::Properties* extensionProperties) { \
|
||||
static oatpp::data::mapping::type::Type::Properties* ptr = Z__CLASS_EXTEND(properties, extensionProperties); \
|
||||
return ptr; \
|
||||
} \
|
||||
public: \
|
||||
TYPE_NAME() \
|
||||
{ \
|
||||
Z__CLASS_INIT_FIELDS(Z__CLASS::Z__CLASS_GET_FIELDS_MAP(), TYPE_EXTEND::Z__CLASS_GET_FIELDS_MAP()); \
|
||||
} \
|
||||
public: \
|
||||
\
|
||||
static ObjectWrapper createShared(){ \
|
||||
return ObjectWrapper(SHARED_DTO_OBJECT_POOL_##TYPE_NAME::allocateShared()); \
|
||||
} \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Properties* Z__CLASS_GET_FIELDS_MAP(){ \
|
||||
static oatpp::data::mapping::type::Type::Properties map = oatpp::data::mapping::type::Type::Properties(); \
|
||||
return ↦ \
|
||||
} \
|
||||
\
|
||||
static oatpp::data::mapping::type::AbstractObjectWrapper Z__CLASS_OBJECT_CREATOR(){ \
|
||||
return oatpp::data::mapping::type::AbstractObjectWrapper(SHARED_DTO_OBJECT_POOL_##TYPE_NAME::allocateShared(), Z__CLASS_GET_TYPE()); \
|
||||
} \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type* Z__CLASS_GET_TYPE(){ \
|
||||
static oatpp::data::mapping::type::Type type(oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID, \
|
||||
#TYPE_NAME, \
|
||||
&Z__CLASS_OBJECT_CREATOR, \
|
||||
Z__CLASS_GET_FIELDS_MAP()); \
|
||||
return &type; \
|
||||
}
|
||||
|
||||
// Fields
|
||||
|
||||
#define OATPP_MACRO_DTO_FIELD_1(TYPE, NAME) \
|
||||
\
|
||||
oatpp::data::mapping::type::Type::Property* Z__CLASS_FIELD_##NAME = \
|
||||
Z__CLASS_GET_FIELD_##NAME(static_cast<oatpp::base::Countable*>(this), \
|
||||
(oatpp::data::mapping::type::AbstractObjectWrapper*)(&NAME)); \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Property* \
|
||||
Z__CLASS_GET_FIELD_##NAME(oatpp::base::Countable* _this, \
|
||||
oatpp::data::mapping::type::AbstractObjectWrapper* _reg) { \
|
||||
static oatpp::data::mapping::type::Type::Property* field = \
|
||||
new oatpp::data::mapping::type::Type::Property(Z__CLASS_GET_FIELDS_MAP(), \
|
||||
(v_int64) _reg - (v_int64) _this, \
|
||||
#NAME, \
|
||||
TYPE::Class::getType()); \
|
||||
return field; \
|
||||
} \
|
||||
\
|
||||
TYPE NAME
|
||||
|
||||
#define OATPP_MACRO_DTO_FIELD_2(TYPE, NAME, QUALIFIER) \
|
||||
\
|
||||
oatpp::data::mapping::type::Type::Property* Z__CLASS_FIELD_##NAME = \
|
||||
Z__CLASS_GET_FIELD_##NAME(static_cast<oatpp::base::Countable*>(this), \
|
||||
(oatpp::data::mapping::type::AbstractObjectWrapper*)(&NAME)); \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Property* \
|
||||
Z__CLASS_GET_FIELD_##NAME(oatpp::base::Countable* _this, \
|
||||
oatpp::data::mapping::type::AbstractObjectWrapper* _reg) { \
|
||||
static oatpp::data::mapping::type::Type::Property* field = \
|
||||
new oatpp::data::mapping::type::Type::Property(Z__CLASS_GET_FIELDS_MAP(), \
|
||||
(v_int64) _reg - (v_int64) _this, \
|
||||
QUALIFIER, \
|
||||
TYPE::Class::getType()); \
|
||||
return field; \
|
||||
} \
|
||||
\
|
||||
TYPE NAME
|
||||
|
||||
/**
|
||||
* Codegen macro to generate fields of DTO object.
|
||||
* @param TYPE - type of the field.
|
||||
* @param NAME - name of the field.
|
||||
* @param QUALIFIER_NAME - additional (optional) field to specify serialized name of the field. If not specified it will be same as NAME.
|
||||
*/
|
||||
#define DTO_FIELD(TYPE, ...) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(OATPP_MACRO_DTO_FIELD_, (__VA_ARGS__)) (TYPE, __VA_ARGS__))
|
178
src/oatpp/codegen/dto/base_define.hpp
Normal file
178
src/oatpp/codegen/dto/base_define.hpp
Normal file
@ -0,0 +1,178 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
* Benedikt-Alexander Mokroß <bam@icognize.de>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
// Defaults
|
||||
|
||||
/**
|
||||
* Codegen macoro to be used in classes extending &id:oatpp::data::mapping::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`.
|
||||
*/
|
||||
#define DTO_INIT(TYPE_NAME, TYPE_EXTEND) \
|
||||
template<class __Z__T__PARAM> \
|
||||
friend class oatpp::data::mapping::type::__class::Object; \
|
||||
public: \
|
||||
typedef TYPE_NAME Z__CLASS; \
|
||||
typedef TYPE_EXTEND Z__CLASS_EXTENDED; \
|
||||
typedef oatpp::data::mapping::type::DTOWrapper<Z__CLASS> ObjectWrapper; \
|
||||
typedef ObjectWrapper __Wrapper; \
|
||||
private: \
|
||||
static const char* Z__CLASS_TYPE_NAME() { \
|
||||
return #TYPE_NAME; \
|
||||
} \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Properties* Z__CLASS_GET_FIELDS_MAP(){ \
|
||||
static oatpp::data::mapping::type::Type::Properties map = oatpp::data::mapping::type::Type::Properties(); \
|
||||
return ↦ \
|
||||
} \
|
||||
public: \
|
||||
\
|
||||
TYPE_NAME() = default; \
|
||||
\
|
||||
template<typename ... Args> \
|
||||
static ObjectWrapper createShared(Args... args){ \
|
||||
return ObjectWrapper(std::make_shared<Z__CLASS>(args...), ObjectWrapper::Class::getType()); \
|
||||
}
|
||||
|
||||
// Fields
|
||||
|
||||
#define OATPP_MACRO_DTO_FIELD_1(TYPE, NAME) \
|
||||
\
|
||||
static v_int64 Z__PROPERTY_OFFSET_##NAME() { \
|
||||
char buffer[sizeof(Z__CLASS)]; \
|
||||
auto obj = static_cast<Z__CLASS*>((void*)buffer); \
|
||||
auto ptr = &obj->NAME; \
|
||||
return (v_int64) ptr - (v_int64) buffer; \
|
||||
} \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Property* Z__PROPERTY_SINGLETON_##NAME() { \
|
||||
static oatpp::data::mapping::type::Type::Property* property = \
|
||||
new oatpp::data::mapping::type::Type::Property(Z__PROPERTY_OFFSET_##NAME(), \
|
||||
#NAME, \
|
||||
TYPE::__Wrapper::Class::getType()); \
|
||||
return property; \
|
||||
} \
|
||||
\
|
||||
static bool Z__PROPERTY_INIT_##NAME(... /* default initializer for all cases */) { \
|
||||
Z__CLASS_GET_FIELDS_MAP()->pushBack(Z__PROPERTY_SINGLETON_##NAME()); \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static TYPE::__Wrapper Z__PROPERTY_INITIALIZER_PROXY_##NAME() { \
|
||||
static bool initialized = Z__PROPERTY_INIT_##NAME(1 /* init info if found */); \
|
||||
return TYPE::__Wrapper(); \
|
||||
} \
|
||||
\
|
||||
TYPE::__Wrapper NAME = Z__PROPERTY_INITIALIZER_PROXY_##NAME()
|
||||
|
||||
#define OATPP_MACRO_DTO_FIELD_2(TYPE, NAME, QUALIFIER) \
|
||||
\
|
||||
static v_int64 Z__PROPERTY_OFFSET_##NAME() { \
|
||||
char buffer[sizeof(Z__CLASS)]; \
|
||||
auto obj = static_cast<Z__CLASS*>((void*)buffer); \
|
||||
auto ptr = &obj->NAME; \
|
||||
return (v_int64) ptr - (v_int64) buffer; \
|
||||
} \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Property* Z__PROPERTY_SINGLETON_##NAME() { \
|
||||
static oatpp::data::mapping::type::Type::Property* property = \
|
||||
new oatpp::data::mapping::type::Type::Property(Z__PROPERTY_OFFSET_##NAME(), \
|
||||
QUALIFIER, \
|
||||
TYPE::__Wrapper::Class::getType()); \
|
||||
return property; \
|
||||
} \
|
||||
\
|
||||
static bool Z__PROPERTY_INIT_##NAME(... /* default initializer for all cases */) { \
|
||||
Z__CLASS_GET_FIELDS_MAP()->pushBack(Z__PROPERTY_SINGLETON_##NAME()); \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static TYPE::__Wrapper Z__PROPERTY_INITIALIZER_PROXY_##NAME() { \
|
||||
static bool initialized = Z__PROPERTY_INIT_##NAME(1 /* init info if found */); \
|
||||
return TYPE::__Wrapper(); \
|
||||
} \
|
||||
\
|
||||
TYPE::__Wrapper NAME = Z__PROPERTY_INITIALIZER_PROXY_##NAME()
|
||||
|
||||
/**
|
||||
* Codegen macro to generate fields of DTO object.
|
||||
* @param TYPE - type of the field.
|
||||
* @param NAME - name of the field.
|
||||
* @param QUALIFIER_NAME - additional (optional) field to specify serialized name of the field. If not specified it will be same as NAME.
|
||||
*/
|
||||
#define DTO_FIELD(TYPE, ...) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(OATPP_MACRO_DTO_FIELD_, (__VA_ARGS__)) (TYPE, __VA_ARGS__))
|
||||
|
||||
// DTO_FIELD_INFO
|
||||
|
||||
#define DTO_FIELD_INFO(NAME) \
|
||||
\
|
||||
static bool Z__PROPERTY_INIT_##NAME(int) { \
|
||||
Z__PROPERTY_INIT_##NAME(); /* call first initialization */ \
|
||||
Z__PROPERTY_ADD_INFO_##NAME(&Z__PROPERTY_SINGLETON_##NAME()->info); \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static void Z__PROPERTY_ADD_INFO_##NAME(oatpp::data::mapping::type::Type::Property::Info* info)
|
||||
|
||||
// FOR EACH
|
||||
|
||||
#define OATPP_MACRO_DTO_HC_EQ_PARAM_HC(INDEX, COUNT, X) \
|
||||
result = ((result << 5) - result) + std::hash<decltype(X)>{}(X);
|
||||
|
||||
#define OATPP_MACRO_DTO_HC_EQ_PARAM_EQ(INDEX, COUNT, X) \
|
||||
&& X == other.X
|
||||
|
||||
#define DTO_HASHCODE_AND_EQUALS(...) \
|
||||
v_uint64 defaultHashCode() const override { \
|
||||
return 1; \
|
||||
} \
|
||||
\
|
||||
bool defaultEquals(const Object& other) const override { \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
v_uint64 hashCode() const { \
|
||||
v_uint64 result = 1; \
|
||||
result = ((result << 5) - result) + static_cast<const Z__CLASS_EXTENDED&>(*this).hashCode(); \
|
||||
OATPP_MACRO_FOREACH(OATPP_MACRO_DTO_HC_EQ_PARAM_HC, __VA_ARGS__) \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool operator==(const Z__CLASS& other) const { \
|
||||
return static_cast<const Z__CLASS_EXTENDED&>(*this) == static_cast<const Z__CLASS_EXTENDED&>(other) \
|
||||
OATPP_MACRO_FOREACH(OATPP_MACRO_DTO_HC_EQ_PARAM_EQ, __VA_ARGS__) \
|
||||
; \
|
||||
} \
|
||||
\
|
||||
bool operator!=(const Z__CLASS& other) const { \
|
||||
return !this->operator==(other); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashcode and Equals macro. <br>
|
||||
* List DTO-fields which should count in hashcode and equals operators.
|
||||
*/
|
||||
#define DTO_HC_EQ(...) DTO_HASHCODE_AND_EQUALS(__VA_ARGS__)
|
44
src/oatpp/codegen/dto/base_undef.hpp
Normal file
44
src/oatpp/codegen/dto/base_undef.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
* Benedikt-Alexander Mokroß <bam@icognize.de>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#undef DTO_INIT
|
||||
|
||||
// Fields
|
||||
|
||||
#undef OATPP_MACRO_DTO_FIELD_1
|
||||
#undef OATPP_MACRO_DTO_FIELD_2
|
||||
#undef DTO_FIELD
|
||||
|
||||
// Fields Info
|
||||
|
||||
#undef DTO_FIELD_INFO
|
||||
|
||||
// Hashcode & Equals
|
||||
|
||||
#undef OATPP_MACRO_DTO_HC_EQ_PARAM_HC
|
||||
#undef OATPP_MACRO_DTO_HC_EQ_PARAM_EQ
|
||||
#undef DTO_HASHCODE_AND_EQUALS
|
||||
#undef DTO_HC_EQ
|
164
src/oatpp/codegen/dto/enum_define.hpp
Normal file
164
src/oatpp/codegen/dto/enum_define.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
* Benedikt-Alexander Mokroß <bam@icognize.de>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_MACRO(MACRO, NAME, PARAM_LIST) MACRO(NAME, PARAM_LIST)
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_NAME(MACRO, NAME, PARAM_LIST) NAME
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_NAME_STR(MACRO, NAME, PARAM_LIST) #NAME
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_VALUE(MACRO, NAME, PARAM_LIST) OATPP_MACRO_FIRSTARG PARAM_LIST
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_VALUE_STR(MACRO, NAME, PARAM_LIST) OATPP_MACRO_FIRSTARG_STR PARAM_LIST
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM(MACRO, NAME, PARAM_LIST) (MACRO, NAME, PARAM_LIST)
|
||||
|
||||
#define VALUE(NAME, ...) OATPP_MACRO_DTO_ENUM_PARAM(OATPP_MACRO_DTO_ENUM_VALUE, NAME, (__VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_MACRO_SELECTOR(MACRO, NAME, ...) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(MACRO, (__VA_ARGS__)) (NAME, __VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// VALUE MACRO
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_VALUE_1(NAME, VAL) \
|
||||
{ \
|
||||
oatpp::data::mapping::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); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_VALUE_2(NAME, VAL, QUALIFIER) \
|
||||
{ \
|
||||
oatpp::data::mapping::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); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_VALUE_3(NAME, VAL, QUALIFIER, DESCRIPTION) \
|
||||
{ \
|
||||
oatpp::data::mapping::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); \
|
||||
}
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_VALUE(NAME, PARAM_LIST) \
|
||||
OATPP_MACRO_DTO_ENUM_MACRO_SELECTOR(OATPP_MACRO_DTO_ENUM_VALUE_, NAME, OATPP_MACRO_UNFOLD_VA_ARGS PARAM_LIST)
|
||||
|
||||
// FOR EACH
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_DECL_FIRST(INDEX, COUNT, X) \
|
||||
OATPP_MACRO_DTO_ENUM_PARAM_NAME X = OATPP_MACRO_DTO_ENUM_PARAM_VALUE X
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_DECL_REST(INDEX, COUNT, X) \
|
||||
, OATPP_MACRO_DTO_ENUM_PARAM_NAME X = OATPP_MACRO_DTO_ENUM_PARAM_VALUE X
|
||||
|
||||
#define OATPP_MACRO_DTO_ENUM_PARAM_PUT(INDEX, COUNT, X) \
|
||||
OATPP_MACRO_DTO_ENUM_PARAM_MACRO X
|
||||
|
||||
// ENUM MACRO
|
||||
|
||||
#define OATPP_ENUM_0(NAME, ORDINAL_TYPE) \
|
||||
enum class NAME : ORDINAL_TYPE {}; \
|
||||
\
|
||||
namespace { \
|
||||
\
|
||||
class Z__OATPP_ENUM_META_##NAME : public oatpp::data::mapping::type::EnumMeta<NAME> { \
|
||||
private: \
|
||||
\
|
||||
static bool init() { \
|
||||
auto& info = *EnumMeta<NAME>::getInfo(); \
|
||||
v_int32 index = 0; \
|
||||
info.nameQualifier = #NAME; \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
\
|
||||
static bool initializer() { \
|
||||
static bool initialized = init(); \
|
||||
return initialized; \
|
||||
} \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
bool Z__OATPP_ENUM_META_INITIALIZER_##NAME = Z__OATPP_ENUM_META_##NAME::initializer(); \
|
||||
\
|
||||
}
|
||||
|
||||
#define OATPP_ENUM_1(NAME, ORDINAL_TYPE, ...) \
|
||||
enum class NAME : ORDINAL_TYPE { \
|
||||
OATPP_MACRO_FOREACH_FIRST_AND_REST( \
|
||||
OATPP_MACRO_DTO_ENUM_PARAM_DECL_FIRST, \
|
||||
OATPP_MACRO_DTO_ENUM_PARAM_DECL_REST, \
|
||||
__VA_ARGS__ \
|
||||
) \
|
||||
}; \
|
||||
\
|
||||
namespace { \
|
||||
\
|
||||
class Z__OATPP_ENUM_META_##NAME : public oatpp::data::mapping::type::EnumMeta<NAME> { \
|
||||
private: \
|
||||
\
|
||||
static bool init() { \
|
||||
auto& info = *EnumMeta<NAME>::getInfo(); \
|
||||
v_int32 index = 0; \
|
||||
info.nameQualifier = #NAME; \
|
||||
OATPP_MACRO_FOREACH(OATPP_MACRO_DTO_ENUM_PARAM_PUT, __VA_ARGS__) \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
public: \
|
||||
\
|
||||
static bool initializer() { \
|
||||
static bool initialized = init(); \
|
||||
return initialized; \
|
||||
} \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
bool Z__OATPP_ENUM_META_INITIALIZER_##NAME = Z__OATPP_ENUM_META_##NAME::initializer(); \
|
||||
\
|
||||
}
|
||||
|
||||
// Chooser
|
||||
|
||||
#define OATPP_ENUM_MACRO_0(NAME, ORDINAL_TYPE) \
|
||||
OATPP_ENUM_0(NAME, ORDINAL_TYPE)
|
||||
|
||||
#define OATPP_ENUM_MACRO_1(NAME, ORDINAL_TYPE, ...) \
|
||||
OATPP_ENUM_1(NAME, ORDINAL_TYPE, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Codegen macoro to be used in `oatpp::web::client::ApiClient` to generate REST API-Calls.
|
||||
* @param METHOD - Http method ("GET", "POST", "PUT", etc.)
|
||||
* @param PATH - Path to endpoint (without host)
|
||||
* @param NAME - Name of the generated method
|
||||
* @return - std::shared_ptr to &id:oatpp::web::protocol::http::incoming::Response;
|
||||
*/
|
||||
#define ENUM(NAME, ...) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_BINARY_SELECTOR(OATPP_ENUM_MACRO_, (__VA_ARGS__)) (NAME, __VA_ARGS__))
|
73
src/oatpp/codegen/dto/enum_undef.hpp
Normal file
73
src/oatpp/codegen/dto/enum_undef.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
* Benedikt-Alexander Mokroß <bam@icognize.de>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_MACRO
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_NAME
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_NAME_STR
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_VALUE
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_VALUE_STR
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM
|
||||
|
||||
#undef VALUE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_MACRO_SELECTOR
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// VALUE MACRO
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_VALUE_1
|
||||
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_VALUE_2
|
||||
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_VALUE_3
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_VALUE
|
||||
|
||||
// FOR EACH
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_DECL_FIRST
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_DECL_REST
|
||||
|
||||
|
||||
#undef OATPP_MACRO_DTO_ENUM_PARAM_PUT
|
||||
|
||||
// ENUM MACRO
|
||||
|
||||
#undef OATPP_ENUM_0
|
||||
|
||||
#undef OATPP_ENUM_1
|
||||
// Chooser
|
||||
|
||||
#undef OATPP_ENUM_MACRO_0
|
||||
|
||||
#undef OATPP_ENUM_MACRO_1
|
||||
|
||||
#undef ENUM
|
@ -29,6 +29,17 @@
|
||||
|
||||
namespace oatpp {
|
||||
|
||||
/**
|
||||
* ObjectWrapper over the void*.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Void Void;
|
||||
|
||||
/**
|
||||
* `Any` - container for mapping-enabled types.
|
||||
* &id:oatpp::data::mapping::type::Any;
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Any Any;
|
||||
|
||||
/**
|
||||
* Mapping-Enabled String type. &id:oatpp::data::mapping::type::String; <br>
|
||||
* For `oatpp::String` methods see &id:oatpp::base::StrBuffer;
|
||||
@ -95,17 +106,66 @@ namespace oatpp {
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Object Object;
|
||||
|
||||
/*
|
||||
* Mapping-Enabled Enum. &id:oatpp::data::mapping::type::Enum;
|
||||
*/
|
||||
template <class T>
|
||||
using Enum = oatpp::data::mapping::type::Enum<T>;
|
||||
|
||||
/*
|
||||
* Mapping-Enabled List. &id:oatpp::data::mapping::type::Vector;
|
||||
*/
|
||||
template <class T>
|
||||
using Vector = oatpp::data::mapping::type::Vector<T>;
|
||||
|
||||
/**
|
||||
* Abstract Vector.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::AbstractVector AbstractVector;
|
||||
|
||||
/*
|
||||
* Mapping-Enabled List. &id:oatpp::data::mapping::type::List;
|
||||
*/
|
||||
template <class T>
|
||||
using List = oatpp::data::mapping::type::List<T>;
|
||||
|
||||
/**
|
||||
* Abstract List.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::AbstractList AbstractList;
|
||||
|
||||
/*
|
||||
* Mapping-Enables ListMap<String, Value>. &id:oatpp::data::mapping::type::ListMap;
|
||||
* Mapping-Enabled UnorderedSet. &id:oatpp::data::mapping::type::UnorderedSet;
|
||||
*/
|
||||
template <class T>
|
||||
using UnorderedSet = oatpp::data::mapping::type::UnorderedSet<T>;
|
||||
|
||||
/**
|
||||
* Abstract UnorderedSet.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::AbstractUnorderedSet AbstractUnorderedSet;
|
||||
|
||||
/*
|
||||
* Mapping-Enables PairList<String, Value>. &id:oatpp::data::mapping::type::PairList;
|
||||
*/
|
||||
template <class Value>
|
||||
using Fields = oatpp::data::mapping::type::ListMap<String, Value>;
|
||||
using Fields = oatpp::data::mapping::type::PairList<String, Value>;
|
||||
|
||||
/**
|
||||
* Abstract Fields
|
||||
*/
|
||||
typedef data::mapping::type::PairListObjectWrapper<oatpp::String, oatpp::Void, data::mapping::type::__class::AbstractPairList> AbstractFields;
|
||||
|
||||
/*
|
||||
* Mapping-Enables PairList<String, Value>. &id:oatpp::data::mapping::type::UnorderedFields;
|
||||
*/
|
||||
template <class Value>
|
||||
using UnorderedFields = oatpp::data::mapping::type::UnorderedMap<String, Value>;
|
||||
|
||||
/**
|
||||
* Abstract UnorderedFields
|
||||
*/
|
||||
typedef data::mapping::type::UnorderedMapObjectWrapper<oatpp::String, oatpp::Void, data::mapping::type::__class::AbstractUnorderedMap> AbstractUnorderedFields;
|
||||
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <stdexcept>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define OATPP_VERSION "1.0.0"
|
||||
#define OATPP_VERSION "1.1.0"
|
||||
|
||||
typedef unsigned char v_char8;
|
||||
typedef v_char8 *p_char8;
|
||||
@ -75,9 +75,11 @@ typedef v_int64 v_counter;
|
||||
* Use this type to define a size for the buffer.
|
||||
*/
|
||||
typedef intptr_t v_buff_size;
|
||||
|
||||
typedef v_buff_size* p_buff_size;
|
||||
|
||||
typedef uintptr_t v_buff_usize;
|
||||
typedef v_buff_usize* p_buff_usize;
|
||||
|
||||
namespace oatpp { namespace base {
|
||||
|
||||
/**
|
||||
|
@ -172,6 +172,9 @@ bool StrBuffer::equals(const void* data, v_buff_size size) const {
|
||||
}
|
||||
|
||||
bool StrBuffer::equals(const char* data) const {
|
||||
if(data == nullptr) {
|
||||
return m_data == nullptr;
|
||||
}
|
||||
if(m_size == (v_buff_size) std::strlen(data)) {
|
||||
return equals(m_data, data, m_size);
|
||||
}
|
||||
@ -179,7 +182,7 @@ bool StrBuffer::equals(const char* data) const {
|
||||
}
|
||||
|
||||
bool StrBuffer::equals(StrBuffer* other) const {
|
||||
return equals((StrBuffer*) this, other);
|
||||
return equals((StrBuffer*)this, other);
|
||||
}
|
||||
|
||||
bool StrBuffer::startsWith(const void* data, v_buff_size size) const {
|
||||
@ -190,6 +193,7 @@ bool StrBuffer::startsWith(const void* data, v_buff_size size) const {
|
||||
}
|
||||
|
||||
bool StrBuffer::startsWith(const char* data) const {
|
||||
if(data == nullptr) return false;
|
||||
v_buff_size length = std::strlen(data);
|
||||
if(m_size >= length) {
|
||||
return equals(m_data, data, length);
|
||||
@ -198,6 +202,7 @@ bool StrBuffer::startsWith(const char* data) const {
|
||||
}
|
||||
|
||||
bool StrBuffer::startsWith(StrBuffer* data) const {
|
||||
if(data == nullptr) return false;
|
||||
if(m_size >= data->m_size) {
|
||||
return equals(m_data, data, data->m_size);
|
||||
}
|
||||
@ -222,21 +227,23 @@ v_buff_size StrBuffer::compare(StrBuffer* str1, StrBuffer* str2) {
|
||||
}
|
||||
|
||||
bool StrBuffer::equals(const void* data1, const void* data2, v_buff_size size) {
|
||||
return (data1 == data2) || (std::memcmp(data1, data2, size) == 0);
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr || data2 == nullptr) return false;
|
||||
return std::memcmp(data1, data2, size) == 0;
|
||||
}
|
||||
|
||||
bool StrBuffer::equals(const char* data1, const char* data2) {
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr && data2 == nullptr) return false;
|
||||
if(data1 == nullptr || data2 == nullptr) return false;
|
||||
const auto size = std::strlen(data1);
|
||||
return (size == std::strlen(data2) && std::memcmp(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool StrBuffer::equals(StrBuffer* str1, StrBuffer* str2) {
|
||||
return (str1 == str2) ||
|
||||
(str1 != nullptr && str2 != nullptr && str1->m_size == str2->m_size &&
|
||||
(str1->m_data == str2->m_data || std::memcmp(str1->m_data, str2->m_data, str1->m_size) == 0)
|
||||
);
|
||||
if(str1 == str2) return true;
|
||||
if(str1 == nullptr || str2 == nullptr) return false;
|
||||
if(str1->m_size != str2->m_size) return false;
|
||||
return str1->m_data == str2->m_data || std::memcmp(str1->m_data, str2->m_data, str1->m_size) == 0;
|
||||
}
|
||||
|
||||
bool StrBuffer::equalsCI(const void* data1, const void* data2, v_buff_size size) {
|
||||
@ -254,16 +261,16 @@ bool StrBuffer::equalsCI(const void* data1, const void* data2, v_buff_size size)
|
||||
|
||||
bool StrBuffer::equalsCI(const char* data1, const char* data2) {
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr && data2 == nullptr) return false;
|
||||
if(data1 == nullptr || data2 == nullptr) return false;
|
||||
const auto size = std::strlen(data1);
|
||||
return (size == std::strlen(data2) && equalsCI(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool StrBuffer::equalsCI(StrBuffer* str1, StrBuffer* str2) {
|
||||
return (str1 == str2) ||
|
||||
(str1 != nullptr && str2 != nullptr && str1->m_size == str2->m_size &&
|
||||
(str1->m_data == str2->m_data || equalsCI(str1->m_data, str2->m_data, str1->m_size))
|
||||
);
|
||||
if(str1 == str2) return true;
|
||||
if(str1 == nullptr || str2 == nullptr) return false;
|
||||
if(str1->m_size != str2->m_size) return false;
|
||||
return (str1->m_data == str2->m_data || equalsCI(str1->m_data, str2->m_data, str1->m_size));
|
||||
}
|
||||
|
||||
bool StrBuffer::equalsCI_FAST(const void* data1, const void* data2, v_buff_size size) {
|
||||
@ -277,16 +284,16 @@ bool StrBuffer::equalsCI_FAST(const void* data1, const void* data2, v_buff_size
|
||||
|
||||
bool StrBuffer::equalsCI_FAST(const char* data1, const char* data2) {
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr && data2 == nullptr) return false;
|
||||
if(data1 == nullptr || data2 == nullptr) return false;
|
||||
const auto size = std::strlen(data1);
|
||||
return (size == std::strlen(data2) && equalsCI_FAST(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool StrBuffer::equalsCI_FAST(StrBuffer* str1, StrBuffer* str2) {
|
||||
return (str1 == str2) ||
|
||||
(str1 != nullptr && str2 != nullptr && str1->m_size == str2->m_size &&
|
||||
(str1->m_data == str2->m_data || equalsCI_FAST(str1->m_data, str2->m_data, str1->m_size))
|
||||
);
|
||||
if(str1 == str2) return true;
|
||||
if(str1 == nullptr || str2 == nullptr) return false;
|
||||
if(str1->m_size != str2->m_size) return false;
|
||||
return (str1->m_data == str2->m_data || equalsCI_FAST(str1->m_data, str2->m_data, str1->m_size));
|
||||
}
|
||||
|
||||
bool StrBuffer::equalsCI_FAST(StrBuffer* str1, const char* str2) {
|
||||
|
@ -36,7 +36,7 @@ const ObjectMapper::Info& ObjectMapper::getInfo() const {
|
||||
return m_info;
|
||||
}
|
||||
|
||||
oatpp::String ObjectMapper::writeToString(const type::AbstractObjectWrapper& variant) const {
|
||||
oatpp::String ObjectMapper::writeToString(const type::Void& variant) const {
|
||||
stream::ChunkedBuffer stream;
|
||||
write(&stream, variant);
|
||||
return stream.toString();
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef oatpp_data_mapping_ObjectMapper_hpp
|
||||
#define oatpp_data_mapping_ObjectMapper_hpp
|
||||
|
||||
#include "type/Object.hpp"
|
||||
#include "type/Object.hpp"
|
||||
#include "type/Type.hpp"
|
||||
|
||||
@ -83,24 +82,22 @@ public:
|
||||
* @param stream - &id:oatpp::data::stream::ConsistentOutputStream; to serialize object to.
|
||||
* @param variant - Object to serialize.
|
||||
*/
|
||||
virtual void write(data::stream::ConsistentOutputStream* stream,
|
||||
const type::AbstractObjectWrapper& variant) const = 0;
|
||||
virtual void write(data::stream::ConsistentOutputStream* stream, const type::Void& variant) const = 0;
|
||||
|
||||
/**
|
||||
* Deserialize object. Implement this method.
|
||||
* @param caret - &id:oatpp::parser::Caret; over serialized buffer.
|
||||
* @param type - pointer to object type. See &id:oatpp::data::mapping::type::Type;.
|
||||
* @return - deserialized object wrapped in &id:oatpp::data::mapping::type::AbstractObjectWrapper;.
|
||||
* @return - deserialized object wrapped in &id:oatpp::Void;.
|
||||
*/
|
||||
virtual mapping::type::AbstractObjectWrapper read(oatpp::parser::Caret& caret,
|
||||
const mapping::type::Type* const type) const = 0;
|
||||
virtual mapping::type::Void read(oatpp::parser::Caret& caret, const mapping::type::Type* const type) const = 0;
|
||||
|
||||
/**
|
||||
* Serialize object to String.
|
||||
* @param variant - Object to serialize.
|
||||
* @return - serialized object as &id:oatpp::String;.
|
||||
*/
|
||||
oatpp::String writeToString(const type::AbstractObjectWrapper& variant) const;
|
||||
oatpp::String writeToString(const type::Void& variant) const;
|
||||
|
||||
/**
|
||||
* Deserialize object.
|
||||
@ -111,9 +108,9 @@ public:
|
||||
* @throws - depends on implementation.
|
||||
*/
|
||||
template<class Class>
|
||||
typename Class::ObjectWrapper readFromCaret(oatpp::parser::Caret& caret) const {
|
||||
auto type = Class::ObjectWrapper::Class::getType();
|
||||
return oatpp::data::mapping::type::static_wrapper_cast<typename Class::ObjectWrapper::ObjectType>(read(caret, type));
|
||||
typename Class::__Wrapper readFromCaret(oatpp::parser::Caret& caret) const {
|
||||
auto type = Class::__Wrapper::Class::getType();
|
||||
return read(caret, type).template staticCast<typename Class::__Wrapper>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,10 +122,10 @@ public:
|
||||
* @throws - depends on implementation.
|
||||
*/
|
||||
template<class Class>
|
||||
typename Class::ObjectWrapper readFromString(const oatpp::String& str) const {
|
||||
auto type = Class::ObjectWrapper::Class::getType();
|
||||
typename Class::__Wrapper readFromString(const oatpp::String& str) const {
|
||||
auto type = Class::__Wrapper::Class::getType();
|
||||
oatpp::parser::Caret caret(str);
|
||||
auto result = oatpp::data::mapping::type::static_wrapper_cast<typename Class::ObjectWrapper::ObjectType>(read(caret, type));
|
||||
auto result = read(caret, type).template staticCast<typename Class::__Wrapper>();
|
||||
if(!result) {
|
||||
throw oatpp::parser::ParsingError(caret.getErrorMessage(), caret.getErrorCode(), caret.getPosition());
|
||||
}
|
||||
|
95
src/oatpp/core/data/mapping/type/Any.cpp
Normal file
95
src/oatpp/core/data/mapping/type/Any.cpp
Normal 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "Any.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId Any::CLASS_ID("Any");
|
||||
}
|
||||
|
||||
Any::Any()
|
||||
: ObjectWrapper(__class::Any::getType())
|
||||
{}
|
||||
|
||||
Any::Any(std::nullptr_t) : Any() {}
|
||||
|
||||
Any::Any(const std::shared_ptr<base::Countable>& ptr, const Type* const type)
|
||||
: ObjectWrapper(std::make_shared<AnyHandle>(ptr, type), __class::Any::getType())
|
||||
{}
|
||||
|
||||
Any::Any(const Any& other)
|
||||
: ObjectWrapper(std::make_shared<AnyHandle>(other.m_ptr->ptr, other.m_ptr->type), __class::Any::getType())
|
||||
{}
|
||||
|
||||
Any::Any(Any&& other)
|
||||
: ObjectWrapper(std::move(other.m_ptr), __class::Any::getType())
|
||||
{}
|
||||
|
||||
const Type* Any::getStoredType() const {
|
||||
if(m_ptr) {
|
||||
return m_ptr->type;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Any& Any::operator=(std::nullptr_t) {
|
||||
m_ptr.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Any& Any::operator=(const Any& other) {
|
||||
if(other) {
|
||||
m_ptr = std::make_shared<AnyHandle>(other.m_ptr->ptr, other.m_ptr->type);
|
||||
} else {
|
||||
m_ptr.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Any& Any::operator=(Any&& other) {
|
||||
m_ptr = std::move(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Any::operator == (std::nullptr_t) const {
|
||||
return m_ptr == nullptr || m_ptr->ptr == nullptr;
|
||||
}
|
||||
|
||||
bool Any::operator != (std::nullptr_t) const {
|
||||
return !operator == (nullptr);
|
||||
}
|
||||
|
||||
bool Any::operator == (const Any& other) const {
|
||||
if(!m_ptr && !other.m_ptr) return true;
|
||||
if(!m_ptr || !other.m_ptr) return false;
|
||||
return m_ptr->ptr.get() == other.m_ptr->ptr.get();
|
||||
}
|
||||
|
||||
bool Any::operator != (const Any& other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
}}}}
|
129
src/oatpp/core/data/mapping/type/Any.hpp
Normal file
129
src/oatpp/core/data/mapping/type/Any.hpp
Normal file
@ -0,0 +1,129 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_type_Any_hpp
|
||||
#define oatpp_data_mapping_type_Any_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "oatpp/core/collection/LinkedList.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class Any {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
|
||||
static Type *getType() {
|
||||
static Type type(CLASS_ID, nullptr);
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class AnyHandle : public base::Countable {
|
||||
public:
|
||||
|
||||
AnyHandle(const std::shared_ptr<void>& objPtr, const Type* const objType)
|
||||
: ptr(objPtr)
|
||||
, type(objType)
|
||||
{}
|
||||
|
||||
std::shared_ptr<void> ptr;
|
||||
const Type* const type;
|
||||
|
||||
};
|
||||
|
||||
class Any : public ObjectWrapper<AnyHandle, __class::Any>{
|
||||
public:
|
||||
typedef Any __Wrapper;
|
||||
public:
|
||||
|
||||
Any();
|
||||
|
||||
Any(std::nullptr_t);
|
||||
|
||||
Any(const Any& other);
|
||||
Any(Any&& other);
|
||||
|
||||
Any(const std::shared_ptr<base::Countable>& ptr, const Type* const type);
|
||||
|
||||
template<class T, class C>
|
||||
Any(const ObjectWrapper<T, C>& polymorph)
|
||||
: ObjectWrapper(std::make_shared<AnyHandle>(polymorph.getPtr(), polymorph.valueType), __class::Any::getType())
|
||||
{}
|
||||
|
||||
template<class T, class C>
|
||||
void store(const ObjectWrapper<T, C>& polymorph) {
|
||||
m_ptr = std::make_shared<AnyHandle>(polymorph.getPtr(), polymorph.valueType);
|
||||
}
|
||||
|
||||
const Type* getStoredType() const;
|
||||
|
||||
template<class WrapperType>
|
||||
typename WrapperType::__Wrapper retrieve() const {
|
||||
|
||||
if(m_ptr) {
|
||||
|
||||
if(m_ptr->type != WrapperType::__Wrapper::Class::getType()) {
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::Any::retrieve()]: Error. The value type doesn't match.");
|
||||
}
|
||||
|
||||
return typename WrapperType::__Wrapper(std::static_pointer_cast<typename WrapperType::__Wrapper::ObjectType>(m_ptr->ptr), m_ptr->type);
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
Any& operator=(std::nullptr_t);
|
||||
|
||||
Any& operator=(const Any& other);
|
||||
Any& operator=(Any&& other);
|
||||
|
||||
template<class T, class C>
|
||||
Any& operator=(const ObjectWrapper<T, C>& polymorph) {
|
||||
m_ptr = std::make_shared<AnyHandle>(polymorph.getPtr(), polymorph.valueType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (std::nullptr_t) const;
|
||||
bool operator != (std::nullptr_t) const;
|
||||
|
||||
bool operator == (const Any& other) const;
|
||||
bool operator != (const Any& other) const;
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif //oatpp_data_mapping_type_Any_hpp
|
33
src/oatpp/core/data/mapping/type/Enum.cpp
Normal file
33
src/oatpp/core/data/mapping/type/Enum.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Enum.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId AbstractEnum::CLASS_ID("Enum");
|
||||
}
|
||||
|
||||
}}}}
|
525
src/oatpp/core/data/mapping/type/Enum.hpp
Normal file
525
src/oatpp/core/data/mapping/type/Enum.hpp
Normal file
@ -0,0 +1,525 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_type_Enum_hpp
|
||||
#define oatpp_data_mapping_type_Enum_hpp
|
||||
|
||||
#include "./Primitive.hpp"
|
||||
#include "oatpp/core/data/share/MemoryLabel.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
/**
|
||||
* Errors of enum interpretation.
|
||||
*/
|
||||
enum class EnumInterpreterError : v_int32 {
|
||||
|
||||
/**
|
||||
* The interpretation was successful.
|
||||
*/
|
||||
OK = 0,
|
||||
|
||||
/**
|
||||
* Wrong `Interpreter` is used to interpret the variable. <br>
|
||||
* This may also occur if for example: <br>
|
||||
* `oatpp::Enum<T>` is passed to interpreter of `oatpp::Enum<T>::NotNull`.
|
||||
*/
|
||||
TYPE_MISMATCH_ENUM = 1,
|
||||
|
||||
/**
|
||||
* Wrong &id:oatpp::data::mapping::type::Primitive; is passed to interpreter.
|
||||
*/
|
||||
TYPE_MISMATCH_ENUM_VALUE = 2,
|
||||
|
||||
/**
|
||||
* Interpreter constraint is violated. <br>
|
||||
* The constraint was set to `NotNull` but interpretation to/from `nullptr` is requested.
|
||||
*/
|
||||
CONSTRAINT_NOT_NULL = 3,
|
||||
|
||||
/**
|
||||
* Enum entry not found.
|
||||
*/
|
||||
ENTRY_NOT_FOUND = 4,
|
||||
|
||||
};
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractEnum {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
public:
|
||||
|
||||
class AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
|
||||
AbstractPolymorphicDispatcher(bool pNotNull)
|
||||
: notNull(pNotNull)
|
||||
{}
|
||||
|
||||
const bool notNull;
|
||||
|
||||
virtual type::Void toInterpretation(const type::Void& enumValue, EnumInterpreterError& error) const = 0;
|
||||
virtual type::Void fromInterpretation(const type::Void& interValue, EnumInterpreterError& error) const = 0;
|
||||
virtual type::Type* getInterpretationType() const = 0;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class T, class Interpreter>
|
||||
class Enum;
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct EnumValueInfo {
|
||||
const T value;
|
||||
const v_int32 index;
|
||||
const data::share::StringKeyLabel name;
|
||||
const data::share::StringKeyLabel description;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct EnumInfo {
|
||||
public:
|
||||
const char* nameQualifier = nullptr;
|
||||
std::unordered_map<data::share::StringKeyLabel, EnumValueInfo<T>> byName;
|
||||
std::unordered_map<v_uint64, EnumValueInfo<T>> byValue;
|
||||
std::vector<EnumValueInfo<T>> byIndex;
|
||||
};
|
||||
|
||||
template<class T, class Interpreter>
|
||||
class EnumObjectWrapper; // FWD
|
||||
|
||||
template<class T>
|
||||
class EnumMeta {
|
||||
|
||||
template<class Type, class Interpreter>
|
||||
friend class __class::Enum;
|
||||
|
||||
template<class Type, class Interpreter>
|
||||
friend class EnumObjectWrapper;
|
||||
|
||||
public:
|
||||
typedef T EnumType;
|
||||
protected:
|
||||
static EnumInfo<T>* getInfo() {
|
||||
static EnumInfo<T> info;
|
||||
return &info;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, bool notnull>
|
||||
class EnumInterpreterAsString {
|
||||
public:
|
||||
typedef String UnderlyingTypeObjectWrapper;
|
||||
public:
|
||||
template <bool N>
|
||||
using InterpreterType = EnumInterpreterAsString<T, N>;
|
||||
public:
|
||||
constexpr static bool notNull = notnull;
|
||||
public:
|
||||
static Void toInterpretation(const Void& enumValue, EnumInterpreterError& error);
|
||||
static Void fromInterpretation(const Void& interValue, EnumInterpreterError& error);
|
||||
static Type* getInterpretationType();
|
||||
};
|
||||
|
||||
template<class T, bool notnull>
|
||||
class EnumInterpreterAsInteger {
|
||||
private:
|
||||
typedef typename std::underlying_type<T>::type EnumUnderlyingType;
|
||||
public:
|
||||
typedef typename ObjectWrapperByUnderlyingType<EnumUnderlyingType>::ObjectWrapper UnderlyingTypeObjectWrapper;
|
||||
public:
|
||||
template <bool N>
|
||||
using InterpreterType = EnumInterpreterAsInteger<T, N>;
|
||||
public:
|
||||
constexpr static bool notNull = notnull;
|
||||
public:
|
||||
static Void toInterpretation(const Void& enumValue, EnumInterpreterError& error);
|
||||
static Void fromInterpretation(const Void& interValue, EnumInterpreterError& error);
|
||||
static Type* getInterpretationType();
|
||||
};
|
||||
|
||||
template<class T, class EnumInterpreter>
|
||||
class EnumObjectWrapper : public ObjectWrapper<T, __class::Enum<T, EnumInterpreter>>{
|
||||
template<class Type, class Interpreter>
|
||||
friend class EnumObjectWrapper;
|
||||
public:
|
||||
typedef EnumObjectWrapper __Wrapper;
|
||||
public:
|
||||
typedef typename std::underlying_type<T>::type UnderlyingEnumType;
|
||||
typedef T Z__EnumType;
|
||||
typedef __class::Enum<T, EnumInterpreter> EnumObjectClass;
|
||||
typedef EnumInterpreter Interpreter;
|
||||
public:
|
||||
typedef EnumObjectWrapper<T, EnumInterpreterAsString<T, EnumInterpreter::notNull>> AsString;
|
||||
typedef EnumObjectWrapper<T, EnumInterpreterAsInteger<T, EnumInterpreter::notNull>> AsNumber;
|
||||
typedef EnumObjectWrapper<T, typename EnumInterpreter::template InterpreterType<true>> NotNull;
|
||||
public:
|
||||
|
||||
EnumObjectWrapper(const std::shared_ptr<T>& ptr, const type::Type* const valueType)
|
||||
: type::ObjectWrapper<T, EnumObjectClass>(ptr, valueType)
|
||||
{}
|
||||
|
||||
EnumObjectWrapper() {}
|
||||
|
||||
EnumObjectWrapper(std::nullptr_t) {}
|
||||
|
||||
EnumObjectWrapper(const std::shared_ptr<T>& ptr)
|
||||
: type::ObjectWrapper<T, EnumObjectClass>(ptr)
|
||||
{}
|
||||
|
||||
EnumObjectWrapper(std::shared_ptr<T>&& ptr)
|
||||
: type::ObjectWrapper<T, EnumObjectClass>(std::forward<std::shared_ptr<T>>(ptr))
|
||||
{}
|
||||
|
||||
template<class OtherInter>
|
||||
EnumObjectWrapper(const EnumObjectWrapper<T, OtherInter>& other)
|
||||
: type::ObjectWrapper<T, EnumObjectClass>(other.getPtr())
|
||||
{}
|
||||
|
||||
template<class OtherInter>
|
||||
EnumObjectWrapper(EnumObjectWrapper<T, OtherInter>&& other)
|
||||
: type::ObjectWrapper<T, EnumObjectClass>(std::move(other.getPtr()))
|
||||
{}
|
||||
|
||||
inline EnumObjectWrapper& operator = (std::nullptr_t) {
|
||||
this->m_ptr.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class OtherInter>
|
||||
inline EnumObjectWrapper& operator = (const EnumObjectWrapper<T, OtherInter>& other) {
|
||||
this->m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class OtherInter>
|
||||
inline EnumObjectWrapper& operator = (EnumObjectWrapper<T, OtherInter>&& other) {
|
||||
this->m_ptr = std::forward<std::shared_ptr<T>>(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
EnumObjectWrapper(T value)
|
||||
: type::ObjectWrapper<T, EnumObjectClass>(std::make_shared<T>(value))
|
||||
{}
|
||||
|
||||
EnumObjectWrapper& operator = (T value) {
|
||||
this->m_ptr = std::make_shared<T>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<TP, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator == (TP){
|
||||
return this->m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<TP, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator != (TP){
|
||||
return this->m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<TP, T>::value, void>::type
|
||||
>
|
||||
inline bool operator == (TP value) const {
|
||||
if(!this->m_ptr) return false;
|
||||
return *this->m_ptr == value;
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<TP, T>::value, void>::type
|
||||
>
|
||||
inline bool operator != (TP value) const {
|
||||
if(!this->m_ptr) return true;
|
||||
return *this->m_ptr != value;
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<typename TP::Z__EnumType, Z__EnumType>::value, void>::type
|
||||
>
|
||||
inline bool operator == (const TP &other) const {
|
||||
if(this->m_ptr.get() == other.m_ptr.get()) return true;
|
||||
if(!this->m_ptr || !other.m_ptr) return false;
|
||||
return *this->m_ptr == *other.m_ptr;
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<typename TP::Z__EnumType, Z__EnumType>::value, void>::type
|
||||
>
|
||||
inline bool operator != (const TP &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
template<typename TP,
|
||||
typename enabled = typename std::enable_if<std::is_same<TP, T>::value, void>::type
|
||||
>
|
||||
inline operator TP() const {
|
||||
return *this->m_ptr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static const EnumValueInfo<T>& getEntryByName(const String& name) {
|
||||
auto it = EnumMeta<T>::getInfo()->byName.find(name);
|
||||
if(it != EnumMeta<T>::getInfo()->byName.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByName()]: Error. Entry not found.");
|
||||
}
|
||||
|
||||
static const EnumValueInfo<T>& getEntryByValue(T value) {
|
||||
auto it = EnumMeta<T>::getInfo()->byValue.find(static_cast<v_uint64>(value));
|
||||
if(it != EnumMeta<T>::getInfo()->byValue.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByValue()]: Error. Entry not found.");
|
||||
}
|
||||
|
||||
static const EnumValueInfo<T>& getEntryByUnderlyingValue(UnderlyingEnumType value) {
|
||||
auto it = EnumMeta<T>::getInfo()->byValue.find(static_cast<v_uint64>(value));
|
||||
if(it != EnumMeta<T>::getInfo()->byValue.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::Enum::getEntryByUnderlyingValue()]: Error. Entry not found.");
|
||||
}
|
||||
|
||||
static const EnumValueInfo<T>& getEntryByIndex(v_int32 index) {
|
||||
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.");
|
||||
}
|
||||
|
||||
static const std::vector<EnumValueInfo<T>>& getEntries() {
|
||||
return EnumMeta<T>::getInfo()->byIndex;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using Enum = EnumObjectWrapper<T, EnumInterpreterAsString<T, false>>;
|
||||
|
||||
template<class T, bool notnull>
|
||||
Void EnumInterpreterAsString<T, notnull>::toInterpretation(const Void& enumValue, EnumInterpreterError& error) {
|
||||
typedef EnumObjectWrapper<T, EnumInterpreterAsString<T, notnull>> EnumOW;
|
||||
|
||||
if(enumValue.valueType != EnumOW::Class::getType()) {
|
||||
error = EnumInterpreterError::TYPE_MISMATCH_ENUM;
|
||||
return Void(nullptr, String::Class::getType());
|
||||
}
|
||||
|
||||
if(!enumValue) {
|
||||
if(notnull) {
|
||||
error = EnumInterpreterError::CONSTRAINT_NOT_NULL;
|
||||
return Void(nullptr, String::Class::getType());
|
||||
}
|
||||
return Void(nullptr, String::Class::getType());
|
||||
}
|
||||
|
||||
const auto& ow = enumValue.staticCast<EnumOW>();
|
||||
const auto& entry = EnumOW::getEntryByValue(*ow);
|
||||
return entry.name.toString();
|
||||
}
|
||||
|
||||
template<class T, bool notnull>
|
||||
Void EnumInterpreterAsString<T, notnull>::fromInterpretation(const Void& interValue, EnumInterpreterError& error) {
|
||||
typedef EnumObjectWrapper<T, EnumInterpreterAsString<T, notnull>> EnumOW;
|
||||
|
||||
if(interValue.valueType != String::Class::getType()) {
|
||||
error = EnumInterpreterError::TYPE_MISMATCH_ENUM_VALUE;
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
|
||||
if(!interValue) {
|
||||
if(notnull) {
|
||||
error = EnumInterpreterError::CONSTRAINT_NOT_NULL;
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
|
||||
try {
|
||||
const auto &entry = EnumObjectWrapper<T, EnumInterpreterAsString<T, notnull>>::getEntryByName(
|
||||
interValue.staticCast<String>()
|
||||
);
|
||||
return EnumOW(entry.value);
|
||||
} catch (const std::runtime_error& e) { // TODO - add a specific error for this.
|
||||
error = EnumInterpreterError::ENTRY_NOT_FOUND;
|
||||
}
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
|
||||
template<class T, bool notnull>
|
||||
Type* EnumInterpreterAsString<T, notnull>::getInterpretationType() {
|
||||
return String::Class::getType();
|
||||
}
|
||||
|
||||
template<class T, bool notnull>
|
||||
Void EnumInterpreterAsInteger<T, notnull>::toInterpretation(const Void& enumValue, EnumInterpreterError& error) {
|
||||
|
||||
typedef EnumObjectWrapper<T, EnumInterpreterAsInteger<T, notnull>> EnumOW;
|
||||
typedef typename std::underlying_type<T>::type EnumUT;
|
||||
typedef typename ObjectWrapperByUnderlyingType<EnumUT>::ObjectWrapper UTOW;
|
||||
|
||||
if(enumValue.valueType != EnumOW::Class::getType()) {
|
||||
error = EnumInterpreterError::TYPE_MISMATCH_ENUM;
|
||||
return Void(nullptr, UTOW::Class::getType());
|
||||
}
|
||||
|
||||
if(!enumValue) {
|
||||
if(notnull) {
|
||||
error = EnumInterpreterError::CONSTRAINT_NOT_NULL;
|
||||
return Void(nullptr, UTOW::Class::getType());
|
||||
}
|
||||
return Void(nullptr, UTOW::Class::getType());
|
||||
}
|
||||
|
||||
const auto& ow = enumValue.staticCast<EnumOW>();
|
||||
return UTOW(static_cast<EnumUT>(*ow));
|
||||
|
||||
}
|
||||
|
||||
template<class T, bool notnull>
|
||||
Void EnumInterpreterAsInteger<T, notnull>::fromInterpretation(const Void& interValue, EnumInterpreterError& error) {
|
||||
typedef EnumObjectWrapper<T, EnumInterpreterAsInteger<T, notnull>> EnumOW;
|
||||
|
||||
typedef typename std::underlying_type<T>::type EnumUT;
|
||||
typedef typename ObjectWrapperByUnderlyingType<EnumUT>::ObjectWrapper OW;
|
||||
|
||||
if(interValue.valueType != OW::Class::getType()) {
|
||||
error = EnumInterpreterError::TYPE_MISMATCH_ENUM_VALUE;
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
|
||||
if(!interValue) {
|
||||
if(notnull) {
|
||||
error = EnumInterpreterError::CONSTRAINT_NOT_NULL;
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
|
||||
try{
|
||||
const auto& entry = EnumOW::getEntryByUnderlyingValue(
|
||||
interValue.staticCast<OW>()
|
||||
);
|
||||
return EnumOW(entry.value);
|
||||
} catch (const std::runtime_error& e) { // TODO - add a specific error for this.
|
||||
error = EnumInterpreterError::ENTRY_NOT_FOUND;
|
||||
}
|
||||
return Void(nullptr, EnumOW::Class::getType());
|
||||
}
|
||||
|
||||
template<class T, bool notnull>
|
||||
Type* EnumInterpreterAsInteger<T, notnull>::getInterpretationType() {
|
||||
typedef typename std::underlying_type<T>::type EnumUT;
|
||||
return ObjectWrapperByUnderlyingType<EnumUT>::ObjectWrapper::Class::getType();
|
||||
}
|
||||
|
||||
namespace __class {
|
||||
|
||||
template<class T, class Interpreter>
|
||||
class Enum : public AbstractEnum {
|
||||
private:
|
||||
|
||||
class PolymorphicDispatcher : public AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
PolymorphicDispatcher()
|
||||
: AbstractPolymorphicDispatcher(Interpreter::notNull)
|
||||
{}
|
||||
|
||||
type::Void toInterpretation(const type::Void& enumValue, EnumInterpreterError& error) const override {
|
||||
return Interpreter::toInterpretation(enumValue, error);
|
||||
}
|
||||
|
||||
type::Void fromInterpretation(const type::Void& interValue, EnumInterpreterError& error) const override {
|
||||
return Interpreter::fromInterpretation(interValue, error);
|
||||
}
|
||||
|
||||
type::Type* getInterpretationType() const override {
|
||||
return Interpreter::getInterpretationType();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<T>(), getType());
|
||||
}
|
||||
|
||||
static Type createType() {
|
||||
Type type(__class::AbstractEnum::CLASS_ID, type::EnumMeta<T>::getInfo()->nameQualifier, &creator, nullptr, new PolymorphicDispatcher());
|
||||
return type;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Type* getType() {
|
||||
static Type type = createType();
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<class T, class I>
|
||||
struct hash <oatpp::data::mapping::type::EnumObjectWrapper<T, I>> {
|
||||
|
||||
typedef oatpp::data::mapping::type::EnumObjectWrapper<T, I> argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const &e) const noexcept {
|
||||
if (e.get() == nullptr) return 0;
|
||||
return static_cast<v_uint64>(*e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // oatpp_data_mapping_type_Enum_hpp
|
@ -27,81 +27,109 @@
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "oatpp/core/collection/LinkedList.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
#include <list>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
|
||||
namespace __class {
|
||||
|
||||
|
||||
class AbstractList {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
public:
|
||||
|
||||
class AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
virtual void addPolymorphicItem(const type::Void& object, const type::Void& item) const = 0;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class List; // FWD
|
||||
|
||||
class List;
|
||||
|
||||
}
|
||||
|
||||
template<class T, class Class>
|
||||
class ListTypeTemplate : public oatpp::collection::LinkedList<T> {
|
||||
friend Class;
|
||||
|
||||
template<class T, class C>
|
||||
class ListObjectWrapper : public type::ObjectWrapper<std::list<T>, C> {
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::ObjectWrapper<ListTypeTemplate, Class> ObjectWrapper;
|
||||
typedef std::list<T> TemplateObjectType;
|
||||
typedef C TemplateObjectClass;
|
||||
public:
|
||||
OBJECT_POOL(DTO_LIST_POOL, ListTypeTemplate, 32)
|
||||
SHARED_OBJECT_POOL(SHARED_DTO_LIST_POOL, ListTypeTemplate, 32)
|
||||
protected:
|
||||
|
||||
static AbstractObjectWrapper Z__CLASS_OBJECT_CREATOR(){
|
||||
return AbstractObjectWrapper(SHARED_DTO_LIST_POOL::allocateShared(), Z__CLASS_GET_TYPE());
|
||||
}
|
||||
|
||||
static Type* Z__CLASS_GET_TYPE(){
|
||||
static Type type(Class::CLASS_ID, nullptr, &Z__CLASS_OBJECT_CREATOR);
|
||||
if(type.params.empty()){
|
||||
type.params.push_back(T::Class::getType());
|
||||
}
|
||||
return &type;
|
||||
}
|
||||
|
||||
public:
|
||||
ListTypeTemplate()
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(ListObjectWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
ListObjectWrapper(std::initializer_list<T> ilist)
|
||||
: type::ObjectWrapper<TemplateObjectType, TemplateObjectClass>(std::make_shared<TemplateObjectType>(ilist))
|
||||
{}
|
||||
public:
|
||||
|
||||
static ObjectWrapper createShared(){
|
||||
return ObjectWrapper(SHARED_DTO_LIST_POOL::allocateShared());
|
||||
|
||||
static ListObjectWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
virtual void addPolymorphicItem(const AbstractObjectWrapper& item){
|
||||
auto ptr = std::static_pointer_cast<typename T::ObjectType>(item.getPtr());
|
||||
this->pushBack(T(ptr, item.valueType));
|
||||
|
||||
ListObjectWrapper& operator = (std::initializer_list<T> ilist) {
|
||||
this->m_ptr = std::make_shared<TemplateObjectType>(ilist);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
T& operator[] (v_buff_usize index) const {
|
||||
auto it = this->m_ptr->begin();
|
||||
std::advance(it, index);
|
||||
return *it;
|
||||
}
|
||||
|
||||
TemplateObjectType& operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using List = ListTypeTemplate<T, __class::List<T>>;
|
||||
|
||||
using List = ListObjectWrapper<typename T::__Wrapper, __class::List<typename T::__Wrapper>>;
|
||||
|
||||
typedef ListObjectWrapper<type::Void, __class::AbstractList> AbstractList;
|
||||
|
||||
namespace __class {
|
||||
|
||||
|
||||
template<class T>
|
||||
class List : public AbstractList {
|
||||
public:
|
||||
|
||||
static Type* getType(){
|
||||
static Type* type = static_cast<Type*>(oatpp::data::mapping::type::List<T>::Z__CLASS_GET_TYPE());
|
||||
private:
|
||||
|
||||
class PolymorphicDispatcher : public AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
|
||||
void addPolymorphicItem(const type::Void& object, const type::Void& item) const override {
|
||||
const auto& list = object.staticCast<type::List<T>>();
|
||||
const auto& listItem = item.staticCast<T>();
|
||||
list->push_back(listItem);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<std::list<T>>(), getType());
|
||||
}
|
||||
|
||||
static Type createType() {
|
||||
Type type(__class::AbstractList::CLASS_ID, nullptr, &creator, nullptr, new PolymorphicDispatcher());
|
||||
type.params.push_back(T::Class::getType());
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
static Type* getType() {
|
||||
static Type type = createType();
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_data_mapping_type_List_hpp */
|
||||
#endif // oatpp_data_mapping_type_List_hpp
|
||||
|
@ -1,102 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_mapping_type_ListMap_hpp
|
||||
#define oatpp_data_mapping_type_ListMap_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
#include "oatpp/core/collection/ListMap.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractListMap {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
};
|
||||
|
||||
template<class Key, class Value>
|
||||
class ListMap; // FWD
|
||||
|
||||
}
|
||||
|
||||
template<class Key, class Value>
|
||||
class ListMap : public oatpp::collection::ListMap<Key, Value> {
|
||||
friend __class::ListMap<Key, Value>;
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::ObjectWrapper<ListMap, __class::ListMap<Key, Value>> ObjectWrapper;
|
||||
public:
|
||||
OBJECT_POOL(DTO_LISTMAP_POOL, ListMap, 32)
|
||||
SHARED_OBJECT_POOL(SHARED_DTO_LISTMAP_POOL, ListMap, 32)
|
||||
protected:
|
||||
|
||||
static AbstractObjectWrapper Z__CLASS_OBJECT_CREATOR(){
|
||||
return AbstractObjectWrapper(SHARED_DTO_LISTMAP_POOL::allocateShared(), Z__CLASS_GET_TYPE());
|
||||
}
|
||||
|
||||
static Type* Z__CLASS_GET_TYPE(){
|
||||
static Type type(__class::AbstractListMap::CLASS_ID, nullptr, &Z__CLASS_OBJECT_CREATOR);
|
||||
if(type.params.empty()){
|
||||
type.params.push_back(Key::Class::getType());
|
||||
type.params.push_back(Value::Class::getType());
|
||||
}
|
||||
return &type;
|
||||
}
|
||||
|
||||
public:
|
||||
ListMap()
|
||||
{}
|
||||
public:
|
||||
|
||||
static ObjectWrapper createShared(){
|
||||
return ObjectWrapper(SHARED_DTO_LISTMAP_POOL::allocateShared());
|
||||
}
|
||||
|
||||
virtual void putPolymorphicItem(const AbstractObjectWrapper& key, const AbstractObjectWrapper& value){
|
||||
auto keyPtr = std::static_pointer_cast<typename Key::ObjectType>(key.getPtr());
|
||||
auto valuePtr = std::static_pointer_cast<typename Value::ObjectType>(value.getPtr());
|
||||
this->put(Key(keyPtr, key.valueType), Value(valuePtr, value.valueType));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
namespace __class {
|
||||
|
||||
template<class Key, class Value>
|
||||
class ListMap : public AbstractListMap{
|
||||
public:
|
||||
|
||||
static Type* getType(){
|
||||
static Type* type = static_cast<Type*>(oatpp::data::mapping::type::ListMap<Key, Value>::Z__CLASS_GET_TYPE());
|
||||
return type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_data_mapping_type_ListMap_hpp */
|
@ -27,13 +27,20 @@
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "./Any.hpp"
|
||||
#include "./Primitive.hpp"
|
||||
#include "./ListMap.hpp"
|
||||
#include "./Enum.hpp"
|
||||
#include "./UnorderedMap.hpp"
|
||||
#include "./PairList.hpp"
|
||||
#include "./List.hpp"
|
||||
#include "./Vector.hpp"
|
||||
#include "./UnorderedSet.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
@ -52,14 +59,31 @@ namespace __class {
|
||||
*/
|
||||
template<class T>
|
||||
class Object : public AbstractObject {
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<T>(), getType());
|
||||
}
|
||||
|
||||
static type::Type::Properties* initProperties() {
|
||||
T obj; // initializer;
|
||||
T::Z__CLASS_EXTEND(T::Z__CLASS::Z__CLASS_GET_FIELDS_MAP(), T::Z__CLASS_EXTENDED::Z__CLASS_GET_FIELDS_MAP());
|
||||
return T::Z__CLASS::Z__CLASS_GET_FIELDS_MAP();
|
||||
}
|
||||
|
||||
static const Type::Properties* propertiesGetter() {
|
||||
static type::Type::Properties* properties = initProperties();
|
||||
return properties;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Get type describing this class.
|
||||
* @return - &id:oatpp::data::mapping::type::Type;
|
||||
*/
|
||||
static Type* getType(){
|
||||
static Type* type = static_cast<Type*>(T::Z__CLASS_GET_TYPE());
|
||||
static Type* getType() {
|
||||
static Type* type = new Type(CLASS_ID, T::Z__CLASS_TYPE_NAME(), creator, propertiesGetter);
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -72,7 +96,11 @@ namespace __class {
|
||||
* For more info about Data Transfer Object (DTO) see [Data Transfer Object (DTO)](https://oatpp.io/docs/components/dto/).
|
||||
*/
|
||||
class Object : public oatpp::base::Countable {
|
||||
template<class T>
|
||||
friend class __class::Object;
|
||||
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;
|
||||
@ -85,26 +113,118 @@ public:
|
||||
typedef oatpp::data::mapping::type::Float32 Float32;
|
||||
typedef oatpp::data::mapping::type::Float64 Float64;
|
||||
typedef oatpp::data::mapping::type::Boolean Boolean;
|
||||
|
||||
template <class T>
|
||||
using Vector = oatpp::data::mapping::type::Vector<T>;
|
||||
|
||||
template <class T>
|
||||
using UnorderedSet = oatpp::data::mapping::type::UnorderedSet<T>;
|
||||
|
||||
template <class T>
|
||||
using List = oatpp::data::mapping::type::List<T>;
|
||||
|
||||
template <class Value>
|
||||
using Fields = oatpp::data::mapping::type::ListMap<String, Value>;
|
||||
protected:
|
||||
using Fields = oatpp::data::mapping::type::PairList<String, Value>;
|
||||
|
||||
template <class Value>
|
||||
using UnorderedFields = oatpp::data::mapping::type::UnorderedMap<String, Value>;
|
||||
|
||||
private:
|
||||
|
||||
static Type::Properties* Z__CLASS_EXTEND(Type::Properties* properties, Type::Properties* extensionProperties) {
|
||||
properties->pushFrontAll(extensionProperties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static oatpp::data::mapping::type::Type::Properties* Z__CLASS_GET_FIELDS_MAP(){
|
||||
static oatpp::data::mapping::type::Type::Properties map;
|
||||
return ↦
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual v_uint64 defaultHashCode() const {
|
||||
return (v_uint64) reinterpret_cast<v_buff_usize>(this);
|
||||
}
|
||||
|
||||
virtual bool defaultEquals(const Object& other) const {
|
||||
return this == &other;
|
||||
}
|
||||
|
||||
v_uint64 hashCode() const {
|
||||
return defaultHashCode();
|
||||
}
|
||||
|
||||
bool operator==(const Object& other) const {
|
||||
return defaultEquals(other);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class ObjT>
|
||||
class DTOWrapper : public ObjectWrapper<ObjT, __class::Object<ObjT>> {
|
||||
public:
|
||||
typedef ObjT TemplateObjectType;
|
||||
typedef __class::Object<ObjT> TemplateObjectClass;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(DTOWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
static DTOWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator == (T){
|
||||
return this->m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator != (T){
|
||||
return this->m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, DTOWrapper>::value, void>::type
|
||||
>
|
||||
inline bool operator == (const T &other) const {
|
||||
if(this->m_ptr.get() == other.m_ptr.get()) return true;
|
||||
if(!this->m_ptr || !other.m_ptr) return false;
|
||||
return *this->m_ptr == *other.m_ptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, DTOWrapper>::value, void>::type
|
||||
>
|
||||
inline bool operator != (const T &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<class T>
|
||||
struct hash<oatpp::data::mapping::type::DTOWrapper<T>> {
|
||||
|
||||
typedef oatpp::data::mapping::type::DTOWrapper<T> argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const &ow) const noexcept {
|
||||
if(ow) {
|
||||
return ow->hashCode();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* oatpp_data_type_Object_hpp */
|
||||
|
@ -22,12 +22,12 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "ListMap.hpp"
|
||||
#include "PairList.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId AbstractListMap::CLASS_ID("ListMap");
|
||||
const ClassId AbstractPairList::CLASS_ID("PairList");
|
||||
}
|
||||
|
||||
}}}}
|
156
src/oatpp/core/data/mapping/type/PairList.hpp
Normal file
156
src/oatpp/core/data/mapping/type/PairList.hpp
Normal file
@ -0,0 +1,156 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_type_PairList_hpp
|
||||
#define oatpp_data_mapping_type_PairList_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractPairList {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
public:
|
||||
|
||||
class AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
virtual void addPolymorphicItem(const type::Void& object, const type::Void& key, const type::Void& value) const = 0;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class Key, class Value>
|
||||
class PairList;
|
||||
|
||||
}
|
||||
|
||||
template<class Key, class Value, class C>
|
||||
class PairListObjectWrapper : public type::ObjectWrapper<std::list<std::pair<Key, Value>>, C> {
|
||||
public:
|
||||
typedef std::list<std::pair<Key, Value>> TemplateObjectType;
|
||||
typedef C TemplateObjectClass;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(PairListObjectWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
PairListObjectWrapper(std::initializer_list<std::pair<Key, Value>> ilist)
|
||||
: type::ObjectWrapper<TemplateObjectType, TemplateObjectClass>(std::make_shared<TemplateObjectType>(ilist))
|
||||
{}
|
||||
|
||||
static PairListObjectWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
PairListObjectWrapper& operator = (std::initializer_list<std::pair<Key, Value>> ilist) {
|
||||
this->m_ptr = std::make_shared<TemplateObjectType>(ilist);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::pair<Key, Value>& operator[] (v_buff_usize index) const {
|
||||
auto it = this->m_ptr->begin();
|
||||
std::advance(it, index);
|
||||
return *it;
|
||||
}
|
||||
|
||||
Value& operator[] (const Key& key) const {
|
||||
auto& list = *(this->m_ptr.get());
|
||||
auto it = list.begin();
|
||||
while(it != list.end()) {
|
||||
if(it->first == key) {
|
||||
return it->second;
|
||||
}
|
||||
it ++;
|
||||
}
|
||||
list.push_back({key, nullptr});
|
||||
return list.back().second;
|
||||
}
|
||||
|
||||
TemplateObjectType& operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class Key, class Value>
|
||||
using PairList = PairListObjectWrapper<
|
||||
typename Key::__Wrapper,
|
||||
typename Value::__Wrapper,
|
||||
__class::PairList<
|
||||
typename Key::__Wrapper,
|
||||
typename Value::__Wrapper
|
||||
>
|
||||
>;
|
||||
|
||||
namespace __class {
|
||||
|
||||
template<class Key, class Value>
|
||||
class PairList : public AbstractPairList {
|
||||
private:
|
||||
|
||||
class PolymorphicDispatcher : public AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
|
||||
void addPolymorphicItem(const type::Void& object, const type::Void& key, const type::Void& value) const override {
|
||||
const auto& map = object.staticCast<type::PairList<Key, Value>>();
|
||||
const auto& k = key.staticCast<Key>();
|
||||
const auto& v = value.staticCast<Value>();
|
||||
map->push_back({k, v});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<std::list<std::pair<Key, Value>>>(), getType());
|
||||
}
|
||||
|
||||
static Type createType() {
|
||||
Type type(__class::AbstractPairList::CLASS_ID, nullptr, &creator, nullptr, new PolymorphicDispatcher());
|
||||
type.params.push_back(Key::Class::getType());
|
||||
type.params.push_back(Value::Class::getType());
|
||||
return type;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Type* getType() {
|
||||
static Type type = createType();
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif // oatpp_data_mapping_type_PairList_hpp
|
@ -59,71 +59,97 @@ namespace __class {
|
||||
/**
|
||||
* Mapping-enables String is &id:type::ObjectWrapper; over &id:oatpp::base::StrBuffer;
|
||||
*/
|
||||
class String : public type::ObjectWrapper<oatpp::base::StrBuffer, __class::String> {
|
||||
class String : public type::ObjectWrapper<base::StrBuffer, __class::String> {
|
||||
public:
|
||||
String(const std::shared_ptr<oatpp::base::StrBuffer>& ptr, const type::Type* const valueType);
|
||||
typedef String __Wrapper;
|
||||
public:
|
||||
String(const std::shared_ptr<base::StrBuffer>& ptr, const type::Type* const valueType);
|
||||
public:
|
||||
|
||||
String() {}
|
||||
|
||||
String(std::nullptr_t) {}
|
||||
|
||||
String(v_buff_size size)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(oatpp::base::StrBuffer::createShared(size))
|
||||
explicit String(v_buff_size size)
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(base::StrBuffer::createShared(size))
|
||||
{}
|
||||
|
||||
String(const char* data, v_buff_size size, bool copyAsOwnData = true)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(oatpp::base::StrBuffer::createShared(data, size, copyAsOwnData))
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(base::StrBuffer::createShared(data, size, copyAsOwnData))
|
||||
{}
|
||||
|
||||
String(const char* data1, v_buff_size size1, const char* data2, v_buff_size size2)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(oatpp::base::StrBuffer::createSharedConcatenated(data1, size1, data2, size2))
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(base::StrBuffer::createSharedConcatenated(data1, size1, data2, size2))
|
||||
{}
|
||||
|
||||
String(const char* data, bool copyAsOwnData = true)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(oatpp::base::StrBuffer::createFromCString(data, copyAsOwnData))
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(base::StrBuffer::createFromCString(data, copyAsOwnData))
|
||||
{}
|
||||
|
||||
String(const std::shared_ptr<oatpp::base::StrBuffer>& ptr)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(ptr)
|
||||
String(const std::shared_ptr<base::StrBuffer>& ptr)
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(ptr)
|
||||
{}
|
||||
|
||||
String(std::shared_ptr<oatpp::base::StrBuffer>&& ptr)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(std::forward<std::shared_ptr<oatpp::base::StrBuffer>>(ptr))
|
||||
String(std::shared_ptr<base::StrBuffer>&& ptr)
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(std::forward<std::shared_ptr<base::StrBuffer>>(ptr))
|
||||
{}
|
||||
|
||||
String(const String& other)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(other)
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(other)
|
||||
{}
|
||||
|
||||
String(String&& other)
|
||||
: type::ObjectWrapper<oatpp::base::StrBuffer, __class::String>(std::forward<String>(other))
|
||||
: type::ObjectWrapper<base::StrBuffer, __class::String>(std::forward<String>(other))
|
||||
{}
|
||||
|
||||
String& operator = (const char* str) {
|
||||
m_ptr = oatpp::base::StrBuffer::createFromCString(str);
|
||||
|
||||
inline String& operator = (std::nullptr_t) {
|
||||
m_ptr.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& operator = (const String& other){
|
||||
|
||||
inline String& operator = (const char* str) {
|
||||
m_ptr = base::StrBuffer::createFromCString(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline String& operator = (const String& other){
|
||||
m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& operator = (String&& other){
|
||||
m_ptr = std::forward<std::shared_ptr<oatpp::base::StrBuffer>>(other.m_ptr);
|
||||
|
||||
inline String& operator = (String&& other){
|
||||
m_ptr = std::forward<std::shared_ptr<base::StrBuffer>>(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const String &other) const {
|
||||
return m_ptr->equals(other.get());
|
||||
|
||||
inline bool operator == (std::nullptr_t) const {
|
||||
return m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
bool operator!=(const String &other) const {
|
||||
return !m_ptr->equals(other.get());
|
||||
|
||||
inline bool operator != (std::nullptr_t) const {
|
||||
return m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
|
||||
inline bool operator == (const char* str) const {
|
||||
if(!m_ptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_ptr->getSize() != std::strlen(str)) return false;
|
||||
return base::StrBuffer::equals(m_ptr->getData(), str, m_ptr->getSize());
|
||||
}
|
||||
|
||||
inline bool operator != (const char* str) const {
|
||||
return !operator == (str);
|
||||
}
|
||||
|
||||
inline bool operator == (const String &other) const {
|
||||
return base::StrBuffer::equals(m_ptr.get(), other.m_ptr.get());
|
||||
}
|
||||
|
||||
inline bool operator != (const String &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
inline explicit operator bool() const {
|
||||
return m_ptr.operator bool();
|
||||
}
|
||||
|
||||
@ -139,188 +165,245 @@ String operator + (const String& a, const String& b);
|
||||
* @tparam Clazz - Class holding static class information.
|
||||
*/
|
||||
template<typename TValueType, class Clazz>
|
||||
class Primitive : public oatpp::base::Countable {
|
||||
class Primitive : public type::ObjectWrapper<TValueType, Clazz> {
|
||||
public:
|
||||
typedef TValueType ValueType;
|
||||
public:
|
||||
OBJECT_POOL(Primitive_Type_Pool, Primitive, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Primitive_Type_Pool, Primitive, 32)
|
||||
typedef TValueType UnderlyingType;
|
||||
public:
|
||||
|
||||
/**
|
||||
* ObjectWrapper template for &l:Primitive;.
|
||||
*/
|
||||
class ObjectWrapper : public type::ObjectWrapper<Primitive, Clazz> {
|
||||
public:
|
||||
ObjectWrapper(const std::shared_ptr<Primitive>& ptr, const type::Type* const valueType)
|
||||
: type::ObjectWrapper<Primitive, Clazz>(ptr)
|
||||
{
|
||||
if(Clazz::getType() != valueType){
|
||||
throw std::runtime_error("Value type does not match");
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
ObjectWrapper()
|
||||
: type::ObjectWrapper<Primitive, Clazz>()
|
||||
{}
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(Primitive, TValueType, Clazz)
|
||||
|
||||
ObjectWrapper(std::nullptr_t)
|
||||
: type::ObjectWrapper<Primitive, Clazz>()
|
||||
{}
|
||||
|
||||
ObjectWrapper(const std::shared_ptr<Primitive>& ptr)
|
||||
: type::ObjectWrapper<Primitive, Clazz>(ptr)
|
||||
{}
|
||||
|
||||
ObjectWrapper(std::shared_ptr<Primitive>&& ptr)
|
||||
: type::ObjectWrapper<Primitive, Clazz>(std::move(ptr))
|
||||
{}
|
||||
|
||||
ObjectWrapper(const ObjectWrapper& other)
|
||||
: type::ObjectWrapper<Primitive, Clazz>(other)
|
||||
{}
|
||||
|
||||
ObjectWrapper(ObjectWrapper&& other)
|
||||
: type::ObjectWrapper<Primitive, Clazz>(std::move(other))
|
||||
{}
|
||||
|
||||
ObjectWrapper(const ValueType& value)
|
||||
: type::ObjectWrapper<Primitive, Clazz>(Primitive::createShared(value))
|
||||
{}
|
||||
|
||||
ObjectWrapper& operator = (const ValueType& value){
|
||||
if(!this->m_ptr){
|
||||
this->m_ptr = Primitive::createShared(value);
|
||||
} else {
|
||||
this->m_ptr.get()->setValue(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectWrapper& operator = (const ObjectWrapper &other){
|
||||
this->m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const ObjectWrapper &other) const {
|
||||
return this->m_ptr->getValue() == other->getValue();
|
||||
}
|
||||
|
||||
bool operator!=(const ObjectWrapper &other) const {
|
||||
return this->m_ptr->getValue() != other->getValue();
|
||||
}
|
||||
|
||||
inline operator ValueType() const {
|
||||
return this->get()->getValue();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
ValueType m_value;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param value - initial value.
|
||||
*/
|
||||
Primitive(const ValueType& value)
|
||||
: m_value(value)
|
||||
Primitive(TValueType value)
|
||||
: type::ObjectWrapper<TValueType, Clazz>(std::make_shared<TValueType>(value))
|
||||
{}
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create shared primitive.
|
||||
* @param value - initial value.
|
||||
* @return - `std::shared_ptr` to Primitive.
|
||||
*/
|
||||
static std::shared_ptr<Primitive> createShared(const ValueType& value){
|
||||
return Shared_Primitive_Type_Pool::allocateShared(value);
|
||||
Primitive& operator = (TValueType value) {
|
||||
this->m_ptr = std::make_shared<TValueType>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shared primitive upcasted to &id:oatpp::base::Countable;.
|
||||
* @param value - initial value.
|
||||
* @return - `std::shared_ptr` to primitive upcasted to &id:oatpp::base::Countable;.
|
||||
*/
|
||||
static std::shared_ptr<Countable> createAbstract(const ValueType& value){
|
||||
return std::static_pointer_cast<Countable>(Shared_Primitive_Type_Pool::allocateShared(value));
|
||||
TValueType operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value.
|
||||
* @param value.
|
||||
*/
|
||||
void setValue(const ValueType& value) {
|
||||
m_value = value;
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator == (T){
|
||||
return this->m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value.
|
||||
* @return - value.
|
||||
*/
|
||||
ValueType getValue() {
|
||||
return m_value;
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator != (T){
|
||||
return this->m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, TValueType>::value, void>::type
|
||||
>
|
||||
inline bool operator == (T value) const {
|
||||
if(!this->m_ptr) return false;
|
||||
return *this->m_ptr == value;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, TValueType>::value, void>::type
|
||||
>
|
||||
inline bool operator != (T value) const {
|
||||
if(!this->m_ptr) return true;
|
||||
return *this->m_ptr != value;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, Primitive>::value, void>::type
|
||||
>
|
||||
inline bool operator == (const T &other) const {
|
||||
if(this->m_ptr.get() == other.m_ptr.get()) return true;
|
||||
if(!this->m_ptr || !other.m_ptr) return false;
|
||||
return *this->m_ptr == *other.m_ptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, Primitive>::value, void>::type
|
||||
>
|
||||
inline bool operator != (const T &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
inline operator TValueType() const {
|
||||
return *this->m_ptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Int8 is an ObjectWrapper over &l:Primitive; and __class::Int8.
|
||||
* ObjectWrapper for Boolean.
|
||||
*/
|
||||
typedef Primitive<v_int8, __class::Int8>::ObjectWrapper Int8;
|
||||
class Boolean : public type::ObjectWrapper<bool, __class::Boolean> {
|
||||
public:
|
||||
typedef bool UnderlyingType;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(Boolean, bool, __class::Boolean)
|
||||
|
||||
Boolean(bool value)
|
||||
: type::ObjectWrapper<bool, __class::Boolean>(std::make_shared<bool>(value))
|
||||
{}
|
||||
|
||||
Boolean& operator = (bool value) {
|
||||
this->m_ptr = std::make_shared<bool>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator == (T){
|
||||
return m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator != (T){
|
||||
return m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, bool>::value, void>::type
|
||||
>
|
||||
inline bool operator == (T value) const {
|
||||
if(!this->m_ptr) return false;
|
||||
return *this->m_ptr == value;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, bool>::value, void>::type
|
||||
>
|
||||
inline bool operator != (T value) const {
|
||||
if(!this->m_ptr) return true;
|
||||
return *this->m_ptr != value;
|
||||
}
|
||||
|
||||
inline bool operator == (const Boolean &other) const {
|
||||
if(this->m_ptr.get() == other.m_ptr.get()) return true;
|
||||
if(!this->m_ptr || !other.m_ptr) return false;
|
||||
return *this->m_ptr == *other.m_ptr;
|
||||
}
|
||||
|
||||
inline bool operator != (const Boolean &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
inline operator bool() const {
|
||||
if(this->m_ptr) {
|
||||
return *(this->m_ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* UInt8 is an ObjectWrapper over &l:Primitive; and __class::UInt8.
|
||||
* Int8 is an ObjectWrapper over `v_int8` and __class::Int8.
|
||||
*/
|
||||
typedef Primitive<v_uint8, __class::UInt8>::ObjectWrapper UInt8;
|
||||
typedef Primitive<v_int8, __class::Int8> Int8;
|
||||
|
||||
/**
|
||||
* Int16 is an ObjectWrapper over &l:Primitive; and __class::Int16.
|
||||
* UInt8 is an ObjectWrapper over `v_uint8` and __class::UInt8.
|
||||
*/
|
||||
typedef Primitive<v_int16, __class::Int16>::ObjectWrapper Int16;
|
||||
typedef Primitive<v_uint8, __class::UInt8> UInt8;
|
||||
|
||||
/**
|
||||
* UInt16 is an ObjectWrapper over &l:Primitive; and __class::UInt16.
|
||||
* Int16 is an ObjectWrapper over `v_int16` and __class::Int16.
|
||||
*/
|
||||
typedef Primitive<v_uint16, __class::UInt16>::ObjectWrapper UInt16;
|
||||
typedef Primitive<v_int16, __class::Int16> Int16;
|
||||
|
||||
/**
|
||||
* Int32 is an ObjectWrapper over &l:Primitive; and __class::Int32.
|
||||
* UInt16 is an ObjectWrapper over `v_uint16` and __class::UInt16.
|
||||
*/
|
||||
typedef Primitive<v_int32, __class::Int32>::ObjectWrapper Int32;
|
||||
typedef Primitive<v_uint16, __class::UInt16> UInt16;
|
||||
|
||||
/**
|
||||
* UInt32 is an ObjectWrapper over &l:Primitive; and __class::UInt32.
|
||||
* Int32 is an ObjectWrapper over `v_int32` and __class::Int32.
|
||||
*/
|
||||
typedef Primitive<v_uint32, __class::UInt32>::ObjectWrapper UInt32;
|
||||
typedef Primitive<v_int32, __class::Int32> Int32;
|
||||
|
||||
/**
|
||||
* Int64 is an ObjectWrapper over &l:Primitive; and __class::Int64.
|
||||
* UInt32 is an ObjectWrapper over `v_uint32` and __class::UInt32.
|
||||
*/
|
||||
typedef Primitive<v_int64, __class::Int64>::ObjectWrapper Int64;
|
||||
typedef Primitive<v_uint32, __class::UInt32> UInt32;
|
||||
|
||||
/**
|
||||
* UInt64 is an ObjectWrapper over &l:Primitive; and __class::UInt64.
|
||||
* Int64 is an ObjectWrapper over `v_int64` and __class::Int64.
|
||||
*/
|
||||
typedef Primitive<v_uint64, __class::UInt64>::ObjectWrapper UInt64;
|
||||
typedef Primitive<v_int64, __class::Int64> Int64;
|
||||
|
||||
/**
|
||||
* Float32 is an ObjectWrapper over &l:Primitive; and __class::Float32.
|
||||
* UInt64 is an ObjectWrapper over `v_uint64` and __class::UInt64.
|
||||
*/
|
||||
typedef Primitive<v_float32, __class::Float32>::ObjectWrapper Float32;
|
||||
typedef Primitive<v_uint64, __class::UInt64> UInt64;
|
||||
|
||||
/**
|
||||
* Float64 is an ObjectWrapper over &l:Primitive; and __class::Float64.
|
||||
* Float32 is an ObjectWrapper over `v_float32` and __class::Float32.
|
||||
*/
|
||||
typedef Primitive<v_float64, __class::Float64>::ObjectWrapper Float64;
|
||||
typedef Primitive<v_float32, __class::Float32> Float32;
|
||||
|
||||
/**
|
||||
* Boolean is an ObjectWrapper over &l:Primitive; and __class::Boolean.
|
||||
* Float64 is an ObjectWrapper over `v_float64` and __class::Float64.
|
||||
*/
|
||||
typedef Primitive<bool, __class::Boolean>::ObjectWrapper Boolean;
|
||||
typedef Primitive<v_float64, __class::Float64> Float64;
|
||||
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_int8> {
|
||||
typedef Int8 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_uint8> {
|
||||
typedef UInt8 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_int16> {
|
||||
typedef Int16 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_uint16> {
|
||||
typedef UInt16 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_int32> {
|
||||
typedef Int32 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_uint32> {
|
||||
typedef UInt32 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_int64> {
|
||||
typedef Int64 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <v_uint64> {
|
||||
typedef UInt64 ObjectWrapper;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ObjectWrapperByUnderlyingType <bool> {
|
||||
typedef Boolean ObjectWrapper;
|
||||
};
|
||||
|
||||
namespace __class {
|
||||
|
||||
@ -466,9 +549,10 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::String> {
|
||||
|
||||
typedef oatpp::data::mapping::type::String argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& s) const noexcept {
|
||||
if(s.get() == nullptr) return 0;
|
||||
|
||||
p_char8 data = s->getData();
|
||||
result_type result = 0;
|
||||
@ -482,6 +566,150 @@ namespace std {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Boolean> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Boolean argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 2;
|
||||
return result_type(*v);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Int8> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int8 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::UInt8> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt8 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Int16> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int16 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::UInt16> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt16 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Int32> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int32 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::UInt32> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt32 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Int64> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int64 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::UInt64> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt64 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return (result_type) *v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Float32> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Float32 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return *((v_uint32*) v.get());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Float64> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Float64 argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return *((result_type*) v.get());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* oatpp_base_Countable_PrimitiveDataTypes_hpp */
|
||||
|
@ -56,9 +56,10 @@ int ClassId::getClassCount() {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Type::Properties
|
||||
|
||||
void Type::Properties::pushBack(Property* property) {
|
||||
Type::Property* Type::Properties::pushBack(Property* property) {
|
||||
m_map.insert({property->name, property});
|
||||
m_list.push_back(property);
|
||||
return property;
|
||||
}
|
||||
|
||||
void Type::Properties::pushFrontAll(Properties* properties) {
|
||||
@ -69,51 +70,40 @@ void Type::Properties::pushFrontAll(Properties* properties) {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Type::Property
|
||||
|
||||
Type::Property::Property(Properties* properties, v_int64 pOffset, const char* pName, Type* pType)
|
||||
Type::Property::Property(v_int64 pOffset, const char* pName, Type* pType)
|
||||
: offset(pOffset)
|
||||
, name(pName)
|
||||
, type(pType)
|
||||
{
|
||||
properties->pushBack(this);
|
||||
}
|
||||
{}
|
||||
|
||||
void Type::Property::set(void* object, const AbstractObjectWrapper& value) {
|
||||
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
|
||||
void Type::Property::set(void* object, const Void& value) {
|
||||
Void* property = (Void*)(((v_int64) object) + offset);
|
||||
*property = value;
|
||||
}
|
||||
|
||||
AbstractObjectWrapper Type::Property::get(void* object) {
|
||||
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
|
||||
Void Type::Property::get(void* object) {
|
||||
Void* property = (Void*)(((v_int64) object) + offset);
|
||||
return *property;
|
||||
}
|
||||
|
||||
AbstractObjectWrapper& Type::Property::getAsRef(void* object) {
|
||||
AbstractObjectWrapper* property = (AbstractObjectWrapper*)(((v_int64) object) + offset);
|
||||
Void& Type::Property::getAsRef(void* object) {
|
||||
Void* property = (Void*)(((v_int64) object) + offset);
|
||||
return *property;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Type
|
||||
|
||||
Type::Type(const ClassId& pClassId, const char* pNameQualifier)
|
||||
: classId(pClassId)
|
||||
, nameQualifier(pNameQualifier)
|
||||
, creator(nullptr)
|
||||
, properties(nullptr)
|
||||
{}
|
||||
|
||||
Type::Type(const ClassId& pClassId, const char* pNameQualifier, Creator pCreator)
|
||||
Type::Type(const ClassId& pClassId,
|
||||
const char* pNameQualifier,
|
||||
Creator pCreator,
|
||||
PropertiesGetter pPropertiesGetter,
|
||||
void* pPolymorphicDispatcher)
|
||||
: classId(pClassId)
|
||||
, nameQualifier(pNameQualifier)
|
||||
, creator(pCreator)
|
||||
, properties(nullptr)
|
||||
{}
|
||||
|
||||
Type::Type(const ClassId& pClassId, const char* pNameQualifier, Creator pCreator, Properties* pProperties)
|
||||
: classId(pClassId)
|
||||
, nameQualifier(pNameQualifier)
|
||||
, creator(pCreator)
|
||||
, properties(pProperties)
|
||||
, propertiesGetter(pPropertiesGetter)
|
||||
, polymorphicDispatcher(pPolymorphicDispatcher)
|
||||
{}
|
||||
|
||||
}}}}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define oatpp_data_type_Type_hpp
|
||||
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
#include "oatpp/core/base/Environment.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
@ -88,80 +89,91 @@ namespace __class {
|
||||
}
|
||||
|
||||
/**
|
||||
* PolymorphicWrapper holds std::shared_ptr to object, object static type, plus object dynamic type information.
|
||||
* @tparam T - Object Type
|
||||
* ObjectWrapper holds std::shared_ptr to object, object static type, plus object dynamic type information.
|
||||
* @tparam T - Object Type.
|
||||
* @tparam Clazz - Static type info.
|
||||
*/
|
||||
template <class T>
|
||||
class PolymorphicWrapper {
|
||||
template <class T, class Clazz = __class::Void>
|
||||
class ObjectWrapper {
|
||||
protected:
|
||||
std::shared_ptr<T> m_ptr;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Convenience self-typedef.
|
||||
*/
|
||||
typedef ObjectWrapper __Wrapper;
|
||||
|
||||
/**
|
||||
* Static object type
|
||||
*/
|
||||
typedef T ObjectType;
|
||||
public:
|
||||
|
||||
/**
|
||||
* PolymorphicWrapper has no static object Class info.
|
||||
* It treats object as of class &id:oatpp::data::mapping::type::__class::Void;.
|
||||
* Static object class information.
|
||||
*/
|
||||
typedef __class::Void Class;
|
||||
typedef Clazz Class;
|
||||
public:
|
||||
|
||||
PolymorphicWrapper(const std::shared_ptr<T>& ptr)
|
||||
|
||||
ObjectWrapper(const std::shared_ptr<T>& ptr)
|
||||
: m_ptr(ptr)
|
||||
, valueType(Class::getType())
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(const std::shared_ptr<T>& ptr, const Type* const type)
|
||||
|
||||
ObjectWrapper(const std::shared_ptr<T>& ptr, const Type* const type)
|
||||
: m_ptr(ptr)
|
||||
, valueType(type)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(std::shared_ptr<T>&& ptr, const Type* const type)
|
||||
|
||||
ObjectWrapper(std::shared_ptr<T>&& ptr, const Type* const type)
|
||||
: m_ptr(std::move(ptr))
|
||||
, valueType(type)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
PolymorphicWrapper()
|
||||
|
||||
ObjectWrapper()
|
||||
: valueType(Class::getType())
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(std::nullptr_t)
|
||||
ObjectWrapper(std::nullptr_t)
|
||||
: valueType(Class::getType())
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(const Type* const type)
|
||||
|
||||
ObjectWrapper(const Type* const type)
|
||||
: valueType(type)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(const PolymorphicWrapper& other)
|
||||
|
||||
ObjectWrapper(const ObjectWrapper& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
, valueType(other.valueType)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(PolymorphicWrapper&& other)
|
||||
|
||||
ObjectWrapper(ObjectWrapper&& other)
|
||||
: m_ptr(std::move(other.m_ptr))
|
||||
, valueType(other.valueType)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper& operator=(const PolymorphicWrapper<T>& other){
|
||||
|
||||
inline ObjectWrapper& operator=(const ObjectWrapper& other){
|
||||
m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolymorphicWrapper& operator=(const PolymorphicWrapper<T>&& other){
|
||||
|
||||
inline ObjectWrapper& operator=(ObjectWrapper&& other){
|
||||
m_ptr = std::move(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator PolymorphicWrapper<oatpp::base::Countable>() const {
|
||||
return PolymorphicWrapper<oatpp::base::Countable>(this->m_ptr, valueType);
|
||||
inline operator ObjectWrapper<void>() const {
|
||||
return ObjectWrapper<void>(this->m_ptr, valueType);
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
|
||||
template<class Wrapper>
|
||||
Wrapper staticCast() const {
|
||||
return Wrapper(std::static_pointer_cast<typename Wrapper::ObjectType>(m_ptr), valueType);
|
||||
}
|
||||
|
||||
inline T* operator->() const {
|
||||
return m_ptr.operator->();
|
||||
}
|
||||
|
||||
@ -176,16 +188,24 @@ public:
|
||||
std::shared_ptr<T> getPtr() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline bool operator == (std::nullptr_t){
|
||||
return m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
inline bool operator != (std::nullptr_t){
|
||||
return m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
inline bool operator == (const PolymorphicWrapper& other){
|
||||
inline bool operator == (const ObjectWrapper& other){
|
||||
return m_ptr.get() == other.m_ptr.get();
|
||||
}
|
||||
|
||||
inline bool operator != (const PolymorphicWrapper& other){
|
||||
inline bool operator != (const ObjectWrapper& other){
|
||||
return m_ptr.get() != other.m_ptr.get();
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
explicit inline operator bool() const {
|
||||
return m_ptr.operator bool();
|
||||
}
|
||||
|
||||
@ -196,90 +216,16 @@ public:
|
||||
const Type* const valueType;
|
||||
|
||||
};
|
||||
|
||||
template<class T, class F>
|
||||
inline PolymorphicWrapper<T> static_wrapper_cast(const F& from){
|
||||
return PolymorphicWrapper<T>(std::static_pointer_cast<T>(from.getPtr()), from.valueType);
|
||||
}
|
||||
|
||||
/**
|
||||
* ObjectWrapper holds std::shared_ptr to object, object static type, object static class information, plus object dynamic type information.
|
||||
* @tparam T - Object type.
|
||||
* @tparam Clazz - Static Object class information.
|
||||
*/
|
||||
template <class T, class Clazz>
|
||||
class ObjectWrapper : public PolymorphicWrapper<T>{
|
||||
public:
|
||||
/**
|
||||
* Object type.
|
||||
*/
|
||||
typedef T ObjectType;
|
||||
public:
|
||||
/**
|
||||
* Static object class information.
|
||||
*/
|
||||
typedef Clazz Class;
|
||||
public:
|
||||
ObjectWrapper(const std::shared_ptr<T>& ptr, const type::Type* const valueType)
|
||||
: PolymorphicWrapper<T>(ptr, Class::getType())
|
||||
{
|
||||
if(Class::getType() != valueType){
|
||||
throw std::runtime_error("Value type does not match");
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
ObjectWrapper()
|
||||
: PolymorphicWrapper<T>(Class::getType())
|
||||
{}
|
||||
|
||||
ObjectWrapper(std::nullptr_t)
|
||||
: PolymorphicWrapper<T>(Class::getType())
|
||||
{}
|
||||
|
||||
ObjectWrapper(const std::shared_ptr<T>& ptr)
|
||||
: PolymorphicWrapper<T>(ptr, Class::getType())
|
||||
{}
|
||||
|
||||
ObjectWrapper(const PolymorphicWrapper<T>& other)
|
||||
: PolymorphicWrapper<T>(other.getPtr(), Class::getType())
|
||||
{}
|
||||
|
||||
ObjectWrapper(PolymorphicWrapper<T>&& other)
|
||||
: PolymorphicWrapper<T>(std::move(other.getPtr()), Class::getType())
|
||||
{}
|
||||
|
||||
ObjectWrapper& operator=(const PolymorphicWrapper<T>& other){
|
||||
if(this->valueType != other.valueType){
|
||||
OATPP_LOGE("ObjectWrapper", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::ObjectWrapper]: Invalid class cast");
|
||||
}
|
||||
PolymorphicWrapper<T>::operator = (other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectWrapper& operator=(const PolymorphicWrapper<T>&& other){
|
||||
if(this->valueType != other.valueType){
|
||||
OATPP_LOGE("ObjectWrapper", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::ObjectWrapper]: Invalid class cast");
|
||||
}
|
||||
PolymorphicWrapper<T>::operator = (std::forward<PolymorphicWrapper<T>>(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
typedef ObjectWrapper<void, __class::Void> Void;
|
||||
|
||||
/**
|
||||
* PolymorphicWrapper over &id:oatpp::base::Countable; object.
|
||||
*/
|
||||
typedef PolymorphicWrapper<oatpp::base::Countable> AbstractObjectWrapper;
|
||||
template <typename T>
|
||||
struct ObjectWrapperByUnderlyingType {};
|
||||
|
||||
/**
|
||||
* Object type data.
|
||||
*/
|
||||
class Type {
|
||||
public:
|
||||
typedef AbstractObjectWrapper (*Creator)();
|
||||
public:
|
||||
class Property; // FWD
|
||||
public:
|
||||
@ -297,7 +243,7 @@ public:
|
||||
* Add property to the end of the list.
|
||||
* @param property
|
||||
*/
|
||||
void pushBack(Property* property);
|
||||
Property* pushBack(Property* property);
|
||||
|
||||
/**
|
||||
* Add all properties to the beginning of the list.
|
||||
@ -329,18 +275,29 @@ public:
|
||||
* Class to map object properties.
|
||||
*/
|
||||
class Property {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Editional Info about Property.
|
||||
*/
|
||||
struct Info {
|
||||
/**
|
||||
* Description.
|
||||
*/
|
||||
std::string description = "";
|
||||
};
|
||||
|
||||
private:
|
||||
const v_int64 offset;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param properties - &l:Type::Properties;*. to push this property to.
|
||||
* @param pOffset - memory offset of object field from object start address.
|
||||
* @param pName - name of the property.
|
||||
* @param pType - &l:Type; of the property.
|
||||
*/
|
||||
Property(Properties* properties, v_int64 pOffset, const char* pName, Type* pType);
|
||||
Property(v_int64 pOffset, const char* pName, Type* pType);
|
||||
|
||||
/**
|
||||
* Property name.
|
||||
@ -352,54 +309,52 @@ public:
|
||||
*/
|
||||
const Type* const type;
|
||||
|
||||
/**
|
||||
* Property additional info.
|
||||
*/
|
||||
Info info;
|
||||
|
||||
/**
|
||||
* Set value of object field mapped by this property.
|
||||
* @param object - object address.
|
||||
* @param value - value to set.
|
||||
*/
|
||||
void set(void* object, const AbstractObjectWrapper& value);
|
||||
void set(void* object, const Void& value);
|
||||
|
||||
/**
|
||||
* Get value of object field mapped by this property.
|
||||
* @param object - object address.
|
||||
* @return - value of the field.
|
||||
*/
|
||||
AbstractObjectWrapper get(void* object);
|
||||
Void get(void* object);
|
||||
|
||||
/**
|
||||
* Get reference to ObjectWrapper of the object field.
|
||||
* @param object - object address.
|
||||
* @return - reference to ObjectWrapper of the object field.
|
||||
*/
|
||||
AbstractObjectWrapper& getAsRef(void* object);
|
||||
Void& getAsRef(void* object);
|
||||
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
typedef Void (*Creator)();
|
||||
typedef const Properties* (*PropertiesGetter)();
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pClassId - type class id.
|
||||
* @param pNameQualifier - type name qualifier.
|
||||
*/
|
||||
Type(const ClassId& pClassId, const char* pNameQualifier);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pClassId - type class id.
|
||||
* @param pNameQualifier - type name qualifier.
|
||||
* @param pCreator - function pointer of Creator - function to create instance of this type.
|
||||
* @param pPropertiesGetter - function to get properties of the type.
|
||||
* @param pPolymorphicDispatcher - dispatcher to correctly address methods of the type.
|
||||
*/
|
||||
Type(const ClassId& pClassId, const char* pNameQualifier, Creator pCreator);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pClassId - type class id.
|
||||
* @param pNameQualifier - type name qualifier.
|
||||
* @param pCreator - function pointer of Creator - function to create instance of this type.
|
||||
* @param pProperties - pointer to type properties.
|
||||
*/
|
||||
Type(const ClassId& pClassId, const char* pNameQualifier, Creator pCreator, Properties* pProperties);
|
||||
Type(const ClassId& pClassId,
|
||||
const char* pNameQualifier,
|
||||
Creator pCreator = nullptr,
|
||||
PropertiesGetter pPropertiesGetter = nullptr,
|
||||
void* pPolymorphicDispatcher = nullptr);
|
||||
|
||||
/**
|
||||
* type class id.
|
||||
@ -422,12 +377,78 @@ public:
|
||||
const Creator creator;
|
||||
|
||||
/**
|
||||
* Pointer to type properties.
|
||||
* PropertiesGetter - function to get properties of the type.
|
||||
*/
|
||||
const Properties* const properties;
|
||||
const PropertiesGetter propertiesGetter;
|
||||
|
||||
/**
|
||||
* PolymorphicDispatcher - is an object to forward polymorphic calls to a correct object of type `Type`.
|
||||
*/
|
||||
const void* const polymorphicDispatcher;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(WRAPPER_NAME, OBJECT_TYPE, OBJECT_CLASS) \
|
||||
public:\
|
||||
typedef WRAPPER_NAME __Wrapper; \
|
||||
public: \
|
||||
WRAPPER_NAME(const std::shared_ptr<OBJECT_TYPE>& ptr, const type::Type* const valueType) \
|
||||
: type::ObjectWrapper<OBJECT_TYPE, OBJECT_CLASS>(ptr, valueType) \
|
||||
{} \
|
||||
public: \
|
||||
\
|
||||
WRAPPER_NAME() {} \
|
||||
\
|
||||
WRAPPER_NAME(std::nullptr_t) {} \
|
||||
\
|
||||
WRAPPER_NAME(const std::shared_ptr<OBJECT_TYPE>& ptr) \
|
||||
: type::ObjectWrapper<OBJECT_TYPE, OBJECT_CLASS>(ptr) \
|
||||
{} \
|
||||
\
|
||||
WRAPPER_NAME(std::shared_ptr<OBJECT_TYPE>&& ptr) \
|
||||
: type::ObjectWrapper<OBJECT_TYPE, OBJECT_CLASS>(std::forward<std::shared_ptr<OBJECT_TYPE>>(ptr)) \
|
||||
{} \
|
||||
\
|
||||
WRAPPER_NAME(const WRAPPER_NAME& other) \
|
||||
: type::ObjectWrapper<OBJECT_TYPE, OBJECT_CLASS>(other) \
|
||||
{} \
|
||||
\
|
||||
WRAPPER_NAME(WRAPPER_NAME&& other) \
|
||||
: type::ObjectWrapper<OBJECT_TYPE, OBJECT_CLASS>(std::forward<WRAPPER_NAME>(other)) \
|
||||
{} \
|
||||
\
|
||||
inline WRAPPER_NAME& operator = (std::nullptr_t) { \
|
||||
this->m_ptr.reset(); \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
inline WRAPPER_NAME& operator = (const WRAPPER_NAME& other) { \
|
||||
this->m_ptr = other.m_ptr; \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
inline WRAPPER_NAME& operator = (WRAPPER_NAME&& other) { \
|
||||
this->m_ptr = std::forward<std::shared_ptr<OBJECT_TYPE>>(other.m_ptr); \
|
||||
return *this; \
|
||||
} \
|
||||
|
||||
|
||||
}}}}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct hash<oatpp::data::mapping::type::Void> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Void argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
return (result_type) v.get();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* oatpp_data_type_Type_hpp */
|
||||
|
33
src/oatpp/core/data/mapping/type/UnorderedMap.cpp
Normal file
33
src/oatpp/core/data/mapping/type/UnorderedMap.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "UnorderedMap.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId AbstractUnorderedMap::CLASS_ID("UnorderedMap");
|
||||
}
|
||||
|
||||
}}}}
|
141
src/oatpp/core/data/mapping/type/UnorderedMap.hpp
Normal file
141
src/oatpp/core/data/mapping/type/UnorderedMap.hpp
Normal 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_mapping_type_UnorderedMap_hpp
|
||||
#define oatpp_data_mapping_type_UnorderedMap_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractUnorderedMap {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
public:
|
||||
|
||||
class AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
virtual void addPolymorphicItem(const type::Void& object, const type::Void& key, const type::Void& value) const = 0;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class Key, class Value>
|
||||
class UnorderedMap;
|
||||
|
||||
}
|
||||
|
||||
template<class Key, class Value, class C>
|
||||
class UnorderedMapObjectWrapper : public type::ObjectWrapper<std::unordered_map<Key, Value>, C> {
|
||||
public:
|
||||
typedef std::unordered_map<Key, Value> TemplateObjectType;
|
||||
typedef C TemplateObjectClass;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(UnorderedMapObjectWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
UnorderedMapObjectWrapper(std::initializer_list<std::pair<const Key, Value>> ilist)
|
||||
: type::ObjectWrapper<TemplateObjectType, TemplateObjectClass>(std::make_shared<TemplateObjectType>(ilist))
|
||||
{}
|
||||
|
||||
static UnorderedMapObjectWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
UnorderedMapObjectWrapper& operator = (std::initializer_list<std::pair<const Key, Value>> ilist) {
|
||||
this->m_ptr = std::make_shared<TemplateObjectType>(ilist);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Value& operator[] (const Key& key) const {
|
||||
return this->m_ptr->operator [] (key);
|
||||
}
|
||||
|
||||
TemplateObjectType& operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class Key, class Value>
|
||||
using UnorderedMap = UnorderedMapObjectWrapper<
|
||||
typename Key::__Wrapper,
|
||||
typename Value::__Wrapper,
|
||||
__class::UnorderedMap<
|
||||
typename Key::__Wrapper,
|
||||
typename Value::__Wrapper
|
||||
>
|
||||
>;
|
||||
|
||||
namespace __class {
|
||||
|
||||
template<class Key, class Value>
|
||||
class UnorderedMap : public AbstractUnorderedMap {
|
||||
private:
|
||||
|
||||
class PolymorphicDispatcher : public AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
|
||||
void addPolymorphicItem(const type::Void& object, const type::Void& key, const type::Void& value) const override {
|
||||
const auto& map = object.staticCast<type::UnorderedMap<Key, Value>>();
|
||||
const auto& k = key.staticCast<Key>();
|
||||
const auto& v = value.staticCast<Value>();
|
||||
map[k] = v;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<std::unordered_map<Key, Value>>(), getType());
|
||||
}
|
||||
|
||||
static Type createType() {
|
||||
Type type(__class::AbstractUnorderedMap::CLASS_ID, nullptr, &creator, nullptr, new PolymorphicDispatcher());
|
||||
type.params.push_back(Key::Class::getType());
|
||||
type.params.push_back(Value::Class::getType());
|
||||
return type;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Type* getType() {
|
||||
static Type type = createType();
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif // oatpp_data_mapping_type_UnorderedMap_hpp
|
33
src/oatpp/core/data/mapping/type/UnorderedSet.cpp
Normal file
33
src/oatpp/core/data/mapping/type/UnorderedSet.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "UnorderedSet.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId AbstractUnorderedSet::CLASS_ID("UnorderedSet");
|
||||
}
|
||||
|
||||
}}}}
|
137
src/oatpp/core/data/mapping/type/UnorderedSet.hpp
Normal file
137
src/oatpp/core/data/mapping/type/UnorderedSet.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_type_UnorderedSet_hpp
|
||||
#define oatpp_data_mapping_type_UnorderedSet_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include <unordered_set>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractUnorderedSet {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
public:
|
||||
|
||||
class AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
virtual void addPolymorphicItem(const type::Void& object, const type::Void& item) const = 0;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class UnorderedSet;
|
||||
|
||||
}
|
||||
|
||||
template<class T, class C>
|
||||
class UnorderedSetObjectWrapper : public type::ObjectWrapper<std::unordered_set<T>, C> {
|
||||
public:
|
||||
typedef std::unordered_set<T> TemplateObjectType;
|
||||
typedef C TemplateObjectClass;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(UnorderedSetObjectWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
UnorderedSetObjectWrapper(std::initializer_list<T> ilist)
|
||||
: type::ObjectWrapper<TemplateObjectType, TemplateObjectClass>(std::make_shared<TemplateObjectType>(ilist))
|
||||
{}
|
||||
|
||||
static UnorderedSetObjectWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
UnorderedSetObjectWrapper& operator = (std::initializer_list<T> ilist) {
|
||||
this->m_ptr = std::make_shared<TemplateObjectType>(ilist);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator[] (const T& key) const {
|
||||
if(this->m_ptr) {
|
||||
auto it = this->m_ptr->find(key);
|
||||
return it != this->m_ptr->end();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TemplateObjectType& operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using UnorderedSet = UnorderedSetObjectWrapper<typename T::__Wrapper, __class::UnorderedSet<typename T::__Wrapper>>;
|
||||
|
||||
typedef UnorderedSetObjectWrapper<type::Void, __class::AbstractUnorderedSet> AbstractUnorderedSet;
|
||||
|
||||
namespace __class {
|
||||
|
||||
template<class T>
|
||||
class UnorderedSet : public AbstractUnorderedSet {
|
||||
private:
|
||||
|
||||
class PolymorphicDispatcher : public AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
|
||||
void addPolymorphicItem(const type::Void& object, const type::Void& item) const override {
|
||||
const auto& set = object.staticCast<type::UnorderedSet<T>>();
|
||||
const auto& setItem = item.staticCast<T>();
|
||||
set->insert(setItem);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<std::unordered_set<T>>(), getType());
|
||||
}
|
||||
|
||||
static Type createType() {
|
||||
Type type(__class::AbstractUnorderedSet::CLASS_ID, nullptr, &creator, nullptr, new PolymorphicDispatcher());
|
||||
type.params.push_back(T::Class::getType());
|
||||
return type;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Type* getType() {
|
||||
static Type type = createType();
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif // oatpp_data_mapping_type_UnorderedSet_hpp
|
33
src/oatpp/core/data/mapping/type/Vector.cpp
Normal file
33
src/oatpp/core/data/mapping/type/Vector.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Vector.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
const ClassId AbstractVector::CLASS_ID("Vector");
|
||||
}
|
||||
|
||||
}}}}
|
133
src/oatpp/core/data/mapping/type/Vector.hpp
Normal file
133
src/oatpp/core/data/mapping/type/Vector.hpp
Normal file
@ -0,0 +1,133 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_type_Vector_hpp
|
||||
#define oatpp_data_mapping_type_Vector_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractVector {
|
||||
public:
|
||||
static const ClassId CLASS_ID;
|
||||
public:
|
||||
|
||||
class AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
virtual void addPolymorphicItem(const type::Void& object, const type::Void& item) const = 0;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class Vector;
|
||||
|
||||
}
|
||||
|
||||
template<class T, class C>
|
||||
class VectorObjectWrapper : public type::ObjectWrapper<std::vector<T>, C> {
|
||||
public:
|
||||
typedef std::vector<T> TemplateObjectType;
|
||||
typedef C TemplateObjectClass;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(VectorObjectWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
VectorObjectWrapper(std::initializer_list<T> ilist)
|
||||
: type::ObjectWrapper<TemplateObjectType, TemplateObjectClass>(std::make_shared<TemplateObjectType>(ilist))
|
||||
{}
|
||||
|
||||
static VectorObjectWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
VectorObjectWrapper& operator = (std::initializer_list<T> ilist) {
|
||||
this->m_ptr = std::make_shared<TemplateObjectType>(ilist);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator[] (v_buff_usize index) const {
|
||||
return this->m_ptr->operator [] (index);
|
||||
}
|
||||
|
||||
TemplateObjectType& operator*() const {
|
||||
return this->m_ptr.operator*();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
using Vector = VectorObjectWrapper<typename T::__Wrapper, __class::Vector<typename T::__Wrapper>>;
|
||||
|
||||
typedef VectorObjectWrapper<type::Void, __class::AbstractVector> AbstractVector;
|
||||
|
||||
namespace __class {
|
||||
|
||||
template<class T>
|
||||
class Vector : public AbstractVector {
|
||||
private:
|
||||
|
||||
class PolymorphicDispatcher : public AbstractPolymorphicDispatcher {
|
||||
public:
|
||||
|
||||
void addPolymorphicItem(const type::Void& object, const type::Void& item) const override {
|
||||
const auto& vector = object.staticCast<type::Vector<T>>();
|
||||
const auto& vectorItem = item.staticCast<T>();
|
||||
vector->push_back(vectorItem);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
static type::Void creator() {
|
||||
return type::Void(std::make_shared<std::vector<T>>(), getType());
|
||||
}
|
||||
|
||||
static Type createType() {
|
||||
Type type(__class::AbstractVector::CLASS_ID, nullptr, &creator, nullptr, new PolymorphicDispatcher());
|
||||
type.params.push_back(T::Class::getType());
|
||||
return type;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static Type* getType() {
|
||||
static Type type = createType();
|
||||
return &type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif // oatpp_data_mapping_type_Vector_hpp
|
@ -39,6 +39,8 @@ namespace oatpp { namespace data { namespace share {
|
||||
*/
|
||||
template<class Key>
|
||||
class LazyStringMap {
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::String String;
|
||||
private:
|
||||
mutable concurrency::SpinLock m_lock;
|
||||
mutable bool m_fullyInitialized;
|
||||
@ -181,7 +183,7 @@ public:
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
oatpp::String get(const Key& key) const {
|
||||
String get(const Key& key) const {
|
||||
|
||||
std::lock_guard<concurrency::SpinLock> lock(m_lock);
|
||||
|
||||
|
@ -42,7 +42,7 @@ StringKeyLabel::StringKeyLabel(const char* constText)
|
||||
: oatpp::data::share::MemoryLabel(nullptr, (p_char8)constText, std::strlen(constText))
|
||||
{}
|
||||
|
||||
StringKeyLabel::StringKeyLabel(const oatpp::String& str)
|
||||
StringKeyLabel::StringKeyLabel(const String& str)
|
||||
: oatpp::data::share::MemoryLabel(str.getPtr(), str->getData(), str->getSize())
|
||||
{}
|
||||
|
||||
@ -54,7 +54,7 @@ StringKeyLabelCI::StringKeyLabelCI(const char* constText)
|
||||
: oatpp::data::share::MemoryLabel(nullptr, (p_char8)constText, std::strlen(constText))
|
||||
{}
|
||||
|
||||
StringKeyLabelCI::StringKeyLabelCI(const oatpp::String& str)
|
||||
StringKeyLabelCI::StringKeyLabelCI(const String& str)
|
||||
: oatpp::data::share::MemoryLabel(str.getPtr(), str->getData(), str->getSize())
|
||||
{}
|
||||
|
||||
@ -66,7 +66,7 @@ StringKeyLabelCI_FAST::StringKeyLabelCI_FAST(const char* constText)
|
||||
: oatpp::data::share::MemoryLabel(nullptr, (p_char8)constText, std::strlen(constText))
|
||||
{}
|
||||
|
||||
StringKeyLabelCI_FAST::StringKeyLabelCI_FAST(const oatpp::String& str)
|
||||
StringKeyLabelCI_FAST::StringKeyLabelCI_FAST(const String& str)
|
||||
: oatpp::data::share::MemoryLabel(str.getPtr(), str->getData(), str->getSize())
|
||||
{}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define oatpp_data_share_MemoryLabel_hpp
|
||||
|
||||
#include "oatpp/core/base/StrBuffer.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace share {
|
||||
|
||||
@ -36,6 +36,8 @@ namespace oatpp { namespace data { namespace share {
|
||||
* You may allocate separate buffer for data copy later once you need it.
|
||||
*/
|
||||
class MemoryLabel {
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::String String;
|
||||
protected:
|
||||
mutable std::shared_ptr<base::StrBuffer> m_memoryHandle;
|
||||
mutable p_char8 m_data;
|
||||
@ -134,8 +136,8 @@ public:
|
||||
* Create oatpp::String from memory label
|
||||
* @return oatpp::String(data, size)
|
||||
*/
|
||||
oatpp::String toString() const {
|
||||
return oatpp::String((const char*) m_data, m_size, true);
|
||||
String toString() const {
|
||||
return String((const char*) m_data, m_size, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,7 +148,15 @@ public:
|
||||
return std::string((const char*) m_data, m_size);
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
inline bool operator==(std::nullptr_t) const {
|
||||
return m_data == nullptr;
|
||||
}
|
||||
|
||||
inline bool operator!=(std::nullptr_t) const {
|
||||
return m_data != nullptr;
|
||||
}
|
||||
|
||||
inline explicit operator bool() const {
|
||||
return m_data != nullptr;
|
||||
}
|
||||
|
||||
@ -164,13 +174,43 @@ public:
|
||||
|
||||
StringKeyLabel(const std::shared_ptr<base::StrBuffer>& memHandle, p_char8 data, v_buff_size size);
|
||||
StringKeyLabel(const char* constText);
|
||||
StringKeyLabel(const oatpp::String& str);
|
||||
|
||||
bool operator==(const StringKeyLabel &other) const {
|
||||
StringKeyLabel(const String& str);
|
||||
|
||||
inline bool operator==(std::nullptr_t) const {
|
||||
return m_data == nullptr;
|
||||
}
|
||||
|
||||
inline bool operator!=(std::nullptr_t) const {
|
||||
return m_data != nullptr;
|
||||
}
|
||||
|
||||
inline bool operator==(const char* str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_size != std::strlen(str)) return false;
|
||||
return base::StrBuffer::equals(m_data, str, m_size);
|
||||
}
|
||||
|
||||
inline bool operator!=(const char* str) const {
|
||||
return !operator==(str);
|
||||
}
|
||||
|
||||
inline bool operator==(const String& str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_size != str->getSize()) return false;
|
||||
return base::StrBuffer::equals(m_data, str->getData(), m_size);
|
||||
}
|
||||
|
||||
inline bool operator!=(const String& str) const {
|
||||
return !operator==(str);
|
||||
}
|
||||
|
||||
inline bool operator==(const StringKeyLabel &other) const {
|
||||
return m_size == other.m_size && base::StrBuffer::equals(m_data, other.m_data, m_size);
|
||||
}
|
||||
|
||||
bool operator!=(const StringKeyLabel &other) const {
|
||||
|
||||
inline bool operator!=(const StringKeyLabel &other) const {
|
||||
return !(m_size == other.m_size && base::StrBuffer::equals(m_data, other.m_data, m_size));
|
||||
}
|
||||
|
||||
@ -188,16 +228,46 @@ public:
|
||||
|
||||
StringKeyLabelCI(const std::shared_ptr<base::StrBuffer>& memHandle, p_char8 data, v_buff_size size);
|
||||
StringKeyLabelCI(const char* constText);
|
||||
StringKeyLabelCI(const oatpp::String& str);
|
||||
|
||||
bool operator==(const StringKeyLabelCI &other) const {
|
||||
StringKeyLabelCI(const String& str);
|
||||
|
||||
inline bool operator==(std::nullptr_t) const {
|
||||
return m_data == nullptr;
|
||||
}
|
||||
|
||||
inline bool operator!=(std::nullptr_t) const {
|
||||
return m_data != nullptr;
|
||||
}
|
||||
|
||||
inline bool operator==(const char* str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_size != std::strlen(str)) return false;
|
||||
return base::StrBuffer::equalsCI(m_data, str, m_size);
|
||||
}
|
||||
|
||||
inline bool operator!=(const char* str) const {
|
||||
return !operator==(str);
|
||||
}
|
||||
|
||||
inline bool operator==(const String& str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_size != str->getSize()) return false;
|
||||
return base::StrBuffer::equalsCI(m_data, str->getData(), m_size);
|
||||
}
|
||||
|
||||
inline bool operator!=(const String& str) const {
|
||||
return !operator==(str);
|
||||
}
|
||||
|
||||
inline bool operator==(const StringKeyLabelCI &other) const {
|
||||
return m_size == other.m_size && base::StrBuffer::equalsCI(m_data, other.m_data, m_size);
|
||||
}
|
||||
|
||||
bool operator!=(const StringKeyLabelCI &other) const {
|
||||
|
||||
inline bool operator!=(const StringKeyLabelCI &other) const {
|
||||
return !(m_size == other.m_size && base::StrBuffer::equalsCI(m_data, other.m_data, m_size));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -208,17 +278,49 @@ public:
|
||||
class StringKeyLabelCI_FAST : public MemoryLabel {
|
||||
public:
|
||||
|
||||
StringKeyLabelCI_FAST() : MemoryLabel() {};
|
||||
|
||||
StringKeyLabelCI_FAST(std::nullptr_t) : MemoryLabel() {}
|
||||
|
||||
StringKeyLabelCI_FAST(const std::shared_ptr<base::StrBuffer>& memHandle, p_char8 data, v_buff_size size);
|
||||
StringKeyLabelCI_FAST(const char* constText);
|
||||
StringKeyLabelCI_FAST(const oatpp::String& str);
|
||||
|
||||
bool operator==(const StringKeyLabelCI_FAST &other) const {
|
||||
StringKeyLabelCI_FAST(const String& str);
|
||||
|
||||
inline bool operator==(std::nullptr_t) const {
|
||||
return m_data == nullptr;
|
||||
}
|
||||
|
||||
inline bool operator!=(std::nullptr_t) const {
|
||||
return m_data != nullptr;
|
||||
}
|
||||
|
||||
inline bool operator==(const char* str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_size != std::strlen(str)) return false;
|
||||
return base::StrBuffer::equalsCI_FAST(m_data, str, m_size);
|
||||
}
|
||||
|
||||
inline bool operator!=(const char* str) const {
|
||||
return !operator==(str);
|
||||
}
|
||||
|
||||
inline bool operator==(const String& str) const {
|
||||
if(m_data == nullptr) return str == nullptr;
|
||||
if(str == nullptr) return false;
|
||||
if(m_size != str->getSize()) return false;
|
||||
return base::StrBuffer::equalsCI_FAST(m_data, str->getData(), m_size);
|
||||
}
|
||||
|
||||
inline bool operator!=(const String& str) const {
|
||||
return !operator==(str);
|
||||
}
|
||||
|
||||
inline bool operator==(const StringKeyLabelCI_FAST &other) const {
|
||||
return m_size == other.m_size && base::StrBuffer::equalsCI_FAST(m_data, other.m_data, m_size);
|
||||
}
|
||||
|
||||
bool operator!=(const StringKeyLabelCI_FAST &other) const {
|
||||
|
||||
inline bool operator!=(const StringKeyLabelCI_FAST &other) const {
|
||||
return !(m_size == other.m_size && base::StrBuffer::equalsCI_FAST(m_data, other.m_data, m_size));
|
||||
}
|
||||
|
||||
@ -232,7 +334,7 @@ namespace std {
|
||||
struct hash<oatpp::data::share::StringKeyLabel> {
|
||||
|
||||
typedef oatpp::data::share::StringKeyLabel argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabel const& s) const noexcept {
|
||||
|
||||
@ -252,7 +354,7 @@ namespace std {
|
||||
struct hash<oatpp::data::share::StringKeyLabelCI> {
|
||||
|
||||
typedef oatpp::data::share::StringKeyLabelCI argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabelCI const& s) const noexcept {
|
||||
|
||||
@ -272,7 +374,7 @@ namespace std {
|
||||
struct hash<oatpp::data::share::StringKeyLabelCI_FAST> {
|
||||
|
||||
typedef oatpp::data::share::StringKeyLabelCI_FAST argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabelCI_FAST const& s) const noexcept {
|
||||
|
||||
|
@ -438,7 +438,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const oatpp::Str
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int8& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Int8(null)>]");
|
||||
return s;
|
||||
@ -446,7 +446,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int8& valu
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt8& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<UInt8(null)>]");
|
||||
return s;
|
||||
@ -454,7 +454,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt8& val
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int16& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Int16(null)>]");
|
||||
return s;
|
||||
@ -462,7 +462,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int16& val
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt16& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<UInt16(null)>]");
|
||||
return s;
|
||||
@ -470,7 +470,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt16& va
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int32& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Int32(null)>]");
|
||||
return s;
|
||||
@ -478,7 +478,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int32& val
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt32& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<UInt32(null)>]");
|
||||
return s;
|
||||
@ -486,7 +486,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt32& va
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int64& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Int64(null)>]");
|
||||
return s;
|
||||
@ -494,7 +494,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Int64& val
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt64& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<UInt64(null)>]");
|
||||
return s;
|
||||
@ -502,7 +502,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const UInt64& va
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Float32& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Float32(null)>]");
|
||||
return s;
|
||||
@ -510,7 +510,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Float32& v
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Float64& value) {
|
||||
if(value.getPtr()) {
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Float64(null)>]");
|
||||
return s;
|
||||
@ -518,7 +518,7 @@ ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Float64& v
|
||||
|
||||
ConsistentOutputStream& operator << (ConsistentOutputStream& s, const Boolean& value) {
|
||||
if(value.getPtr()) { // use getPtr() here to avoid false to nullptr conversion
|
||||
return operator << (s, value->getValue());
|
||||
return operator << (s, *value);
|
||||
}
|
||||
s.writeSimple("[<Boolean(null)>]");
|
||||
return s;
|
||||
|
@ -26,8 +26,8 @@
|
||||
* This file contains source code for basic helper macros used for code-generator.
|
||||
*/
|
||||
|
||||
#ifndef oatpp_macro_ForEach_hpp
|
||||
#define oatpp_macro_ForEach_hpp
|
||||
#ifndef oatpp_macro_basic_hpp
|
||||
#define oatpp_macro_basic_hpp
|
||||
|
||||
#define OATPP_MACRO_FOREACH_EXAMPLE_FUNC(INDEX, COUNT, X) \
|
||||
ENV::log("macro", "param: %d/%d: '%s'", INDEX, COUNT, #X);
|
||||
@ -498,4 +498,4 @@ OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 99, N, M, OATPP_MACRO_FIRSTARG_E
|
||||
OATPP_MACRO_FOREACH_98(N, M, OATPP_MACRO_RESTARGS(__VA_ARGS__))
|
||||
|
||||
|
||||
#endif /* oatpp_macro_ForEach_hpp */
|
||||
#endif /* oatpp_macro_basic_hpp */
|
||||
|
@ -35,14 +35,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef codegen_hpp
|
||||
#define codegen_hpp
|
||||
#ifndef oatpp_macro_codegen_hpp
|
||||
#define oatpp_macro_codegen_hpp
|
||||
|
||||
#include "./basic.hpp"
|
||||
|
||||
#define OATPP_MACRO_CODEGEN_EXPAND(X) OATPP_MACRO_STR(X)
|
||||
#define OATPP_CODEGEN_DEFINE_ApiController "oatpp/codegen/ApiController_define.hpp"
|
||||
#define OATPP_CODEGEN_UNDEF_ApiController "oatpp/codegen/ApiController_undef.hpp"
|
||||
|
||||
#define OATPP_CODEGEN_BEGIN(NAME) OATPP_MACRO_CODEGEN_EXPAND(OATPP_MACRO_CONCAT2(oatpp/codegen/codegen_define_, NAME##_.hpp))
|
||||
#define OATPP_CODEGEN_END(NAME) OATPP_MACRO_CODEGEN_EXPAND(OATPP_MACRO_CONCAT2(oatpp/codegen/codegen_undef_, NAME##_.hpp))
|
||||
#define OATPP_CODEGEN_DEFINE_ApiClient "oatpp/codegen/ApiClient_define.hpp"
|
||||
#define OATPP_CODEGEN_UNDEF_ApiClient "oatpp/codegen/ApiClient_undef.hpp"
|
||||
|
||||
#endif /* codegen_hpp */
|
||||
#define OATPP_CODEGEN_DEFINE_DTO "oatpp/codegen/DTO_define.hpp"
|
||||
#define OATPP_CODEGEN_UNDEF_DTO "oatpp/codegen/DTO_undef.hpp"
|
||||
|
||||
#define OATPP_CODEGEN_BEGIN(NAME) OATPP_MACRO_EXPAND(OATPP_CODEGEN_DEFINE_ ## NAME)
|
||||
#define OATPP_CODEGEN_END(NAME) OATPP_MACRO_EXPAND(OATPP_CODEGEN_UNDEF_ ## NAME)
|
||||
|
||||
#endif /* oatpp_macro_codegen_hpp */
|
||||
|
@ -61,13 +61,17 @@ v_io_size Beautifier::write(const void *data, v_buff_size count, async::Action&
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(c) {
|
||||
|
||||
case '\\': {
|
||||
if(m_isInString) {
|
||||
if(c == '\\') {
|
||||
m_isCharEscaped = true;
|
||||
buffer.writeCharSimple('\\');
|
||||
break;
|
||||
} else if(c == '"') {
|
||||
m_isInString = false;
|
||||
}
|
||||
buffer.writeCharSimple(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(c) {
|
||||
|
||||
case '{': {
|
||||
if(m_wantIndent) {
|
||||
@ -121,20 +125,20 @@ v_io_size Beautifier::write(const void *data, v_buff_size count, async::Action&
|
||||
}
|
||||
buffer.writeCharSimple('"');
|
||||
m_wantIndent = false;
|
||||
m_isInString = !m_isInString;
|
||||
m_isInString = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case ':': {
|
||||
if(!m_isInString) {
|
||||
buffer.writeSimple(": ", 2);
|
||||
} else {
|
||||
buffer.writeCharSimple(':');
|
||||
}
|
||||
buffer.writeSimple(": ", 2);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if(m_wantIndent) {
|
||||
writeIndent(&buffer);
|
||||
m_wantIndent = false;
|
||||
}
|
||||
buffer.writeCharSimple(c);
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "Deserializer.hpp"
|
||||
|
||||
#include "oatpp/parser/json/Utils.hpp"
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
@ -35,27 +34,34 @@ Deserializer::Deserializer(const std::shared_ptr<Config>& config)
|
||||
|
||||
m_methods.resize(data::mapping::type::ClassId::getClassCount(), nullptr);
|
||||
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::String::CLASS_ID, &Deserializer::deserializeString);
|
||||
setDeserializerMethod(data::mapping::type::__class::String::CLASS_ID, &Deserializer::deserializeString);
|
||||
setDeserializerMethod(data::mapping::type::__class::Any::CLASS_ID, &Deserializer::deserializeAny);
|
||||
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::Int8::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int8>);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::UInt8::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt8>);
|
||||
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(oatpp::data::mapping::type::__class::Int16::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int16>);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::UInt16::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt16>);
|
||||
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(oatpp::data::mapping::type::__class::Int32::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int32>);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::UInt32::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt32>);
|
||||
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(oatpp::data::mapping::type::__class::Int64::CLASS_ID, &Deserializer::deserializeInt<oatpp::Int64>);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::UInt64::CLASS_ID, &Deserializer::deserializeUInt<oatpp::UInt64>);
|
||||
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(oatpp::data::mapping::type::__class::Float32::CLASS_ID, &Deserializer::deserializeFloat32);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::Float64::CLASS_ID, &Deserializer::deserializeFloat64);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::Boolean::CLASS_ID, &Deserializer::deserializeBoolean);
|
||||
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(oatpp::data::mapping::type::__class::AbstractList::CLASS_ID, &Deserializer::deserializeList);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID, &Deserializer::deserializeFieldsMap);
|
||||
setDeserializerMethod(oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID, &Deserializer::deserializeObject);
|
||||
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::deserializeList<oatpp::AbstractVector>);
|
||||
setDeserializerMethod(data::mapping::type::__class::AbstractList::CLASS_ID, &Deserializer::deserializeList<oatpp::AbstractList>);
|
||||
setDeserializerMethod(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Deserializer::deserializeList<oatpp::AbstractUnorderedSet>);
|
||||
|
||||
setDeserializerMethod(data::mapping::type::__class::AbstractPairList::CLASS_ID, &Deserializer::deserializeKeyValue<oatpp::AbstractFields>);
|
||||
setDeserializerMethod(data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Deserializer::deserializeKeyValue<oatpp::AbstractUnorderedFields>);
|
||||
|
||||
}
|
||||
|
||||
@ -149,201 +155,148 @@ void Deserializer::skipValue(oatpp::parser::Caret& caret){
|
||||
}
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeFloat32(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
oatpp::Void Deserializer::deserializeFloat32(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
(void) deserializer;
|
||||
(void) type;
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(Float32::ObjectWrapper::Class::getType());
|
||||
return oatpp::Void(Float32::ObjectWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractObjectWrapper(Float32::ObjectType::createAbstract(caret.parseFloat32()), Float32::ObjectWrapper::Class::getType());
|
||||
return Float32(caret.parseFloat32());
|
||||
}
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeFloat64(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
oatpp::Void Deserializer::deserializeFloat64(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
(void) deserializer;
|
||||
(void) type;
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(Float64::ObjectWrapper::Class::getType());
|
||||
return oatpp::Void(Float64::ObjectWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractObjectWrapper(Float64::ObjectType::createAbstract(caret.parseFloat64()), Float64::ObjectWrapper::Class::getType());
|
||||
return Float64(caret.parseFloat64());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeBoolean(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
oatpp::Void Deserializer::deserializeBoolean(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
(void) deserializer;
|
||||
(void) type;
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(Boolean::ObjectWrapper::Class::getType());
|
||||
return oatpp::Void(Boolean::ObjectWrapper::Class::getType());
|
||||
} else {
|
||||
if(caret.isAtText("true", true)) {
|
||||
return AbstractObjectWrapper(Boolean::ObjectType::createAbstract(true), Boolean::ObjectWrapper::Class::getType());
|
||||
return Boolean(true);
|
||||
} else if(caret.isAtText("false", true)) {
|
||||
return AbstractObjectWrapper(Boolean::ObjectType::createAbstract(false), Boolean::ObjectWrapper::Class::getType());
|
||||
return Boolean(false);
|
||||
} else {
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::readBooleanValue()]: Error. 'true' or 'false' - expected.", ERROR_CODE_VALUE_BOOLEAN);
|
||||
return AbstractObjectWrapper(Boolean::ObjectWrapper::Class::getType());
|
||||
return oatpp::Void(Boolean::ObjectWrapper::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeString(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
oatpp::Void Deserializer::deserializeString(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
(void) deserializer;
|
||||
(void) type;
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(String::Class::getType());
|
||||
return oatpp::Void(String::Class::getType());
|
||||
} else {
|
||||
return AbstractObjectWrapper(oatpp::parser::json::Utils::parseString(caret).getPtr(), String::Class::getType());
|
||||
return oatpp::Void(oatpp::parser::json::Utils::parseString(caret).getPtr(), String::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeList(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(type);
|
||||
}
|
||||
|
||||
if(caret.canContinueAtChar('[', 1)) {
|
||||
|
||||
auto listWrapper = type->creator();
|
||||
oatpp::data::mapping::type::PolymorphicWrapper<AbstractList>
|
||||
list(std::static_pointer_cast<AbstractList>(listWrapper.getPtr()), listWrapper.valueType);
|
||||
|
||||
Type* itemType = *type->params.begin();
|
||||
|
||||
caret.skipBlankChars();
|
||||
|
||||
while(!caret.isAtChar(']') && caret.canContinue()){
|
||||
|
||||
caret.skipBlankChars();
|
||||
auto item = deserializer->deserialize(caret, itemType);
|
||||
if(caret.hasError()){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
list->addPolymorphicItem(item);
|
||||
caret.skipBlankChars();
|
||||
|
||||
caret.canContinueAtChar(',', 1);
|
||||
const data::mapping::type::Type* Deserializer::guessNumberType(oatpp::parser::Caret& caret) {
|
||||
return Float64::Class::getType();
|
||||
}
|
||||
|
||||
const data::mapping::type::Type* Deserializer::guessType(oatpp::parser::Caret& caret) {
|
||||
{
|
||||
parser::Caret::StateSaveGuard stateGuard(caret);
|
||||
v_char8 c = *caret.getCurrData();
|
||||
switch (c) {
|
||||
case '"':
|
||||
return String::Class::getType();
|
||||
case '{':
|
||||
return oatpp::Fields<Any>::ObjectWrapper::Class::getType();
|
||||
case '[':
|
||||
return oatpp::List<Any>::ObjectWrapper::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::parser::json::mapping::Deserializer::guessType()]: Error. Can't guess type for oatpp::Any.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!caret.canContinueAtChar(']', 1)){
|
||||
if(!caret.hasError()){
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::readList()]: Error. ']' - expected", ERROR_CODE_ARRAY_SCOPE_CLOSE);
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
return AbstractObjectWrapper(list.getPtr(), list.valueType);
|
||||
oatpp::Void Deserializer::deserializeAny(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
(void) type;
|
||||
if(caret.isAtText("null", true)){
|
||||
return oatpp::Void(Any::Class::getType());
|
||||
} else {
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::readList()]: Error. '[' - expected", ERROR_CODE_ARRAY_SCOPE_OPEN);
|
||||
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.valueType);
|
||||
return oatpp::Void(anyHandle, Any::Class::getType());
|
||||
}
|
||||
}
|
||||
return oatpp::Void(Any::Class::getType());
|
||||
}
|
||||
|
||||
oatpp::Void Deserializer::deserializeEnum(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
auto polymorphicDispatcher = static_cast<const data::mapping::type::__class::AbstractEnum::AbstractPolymorphicDispatcher*>(
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeFieldsMap(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(type);
|
||||
if(e == data::mapping::type::EnumInterpreterError::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if(caret.canContinueAtChar('{', 1)) {
|
||||
|
||||
auto mapWrapper = type->creator();
|
||||
oatpp::data::mapping::type::PolymorphicWrapper<AbstractFieldsMap>
|
||||
map(std::static_pointer_cast<AbstractFieldsMap>(mapWrapper.getPtr()), mapWrapper.valueType);
|
||||
|
||||
auto it = type->params.begin();
|
||||
Type* keyType = *it ++;
|
||||
if(keyType->classId.id != oatpp::data::mapping::type::__class::String::CLASS_ID.id){
|
||||
throw std::runtime_error("[oatpp::parser::json::mapping::Deserializer::readListMap()]: Invalid json map key. Key should be String");
|
||||
}
|
||||
Type* valueType = *it;
|
||||
|
||||
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::parser::json::mapping::Deserializer::readListMap()]: Error. ':' - expected", ERROR_CODE_OBJECT_SCOPE_COLON_MISSING);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
caret.skipBlankChars();
|
||||
|
||||
map->putPolymorphicItem(key, deserializer->deserialize(caret, valueType));
|
||||
|
||||
caret.skipBlankChars();
|
||||
caret.canContinueAtChar(',', 1);
|
||||
|
||||
}
|
||||
|
||||
if(!caret.canContinueAtChar('}', 1)){
|
||||
if(!caret.hasError()){
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::readListMap()]: Error. '}' - expected", ERROR_CODE_OBJECT_SCOPE_CLOSE);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return AbstractObjectWrapper(map.getPtr(), map.valueType);
|
||||
|
||||
} else {
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::readListMap()]: Error. '{' - expected", ERROR_CODE_OBJECT_SCOPE_OPEN);
|
||||
switch(e) {
|
||||
case data::mapping::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::deserializeEnum()]: Error. Enum constraint violated - 'NotNull'.");
|
||||
break;
|
||||
default:
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::deserializeEnum()]: Error. Can't deserialize Enum.");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserializeObject(Deserializer* deserializer,
|
||||
parser::Caret& caret,
|
||||
const Type* const type)
|
||||
{
|
||||
oatpp::Void Deserializer::deserializeObject(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(type);
|
||||
return oatpp::Void(type);
|
||||
}
|
||||
|
||||
if(caret.canContinueAtChar('{', 1)) {
|
||||
|
||||
auto object = type->creator();
|
||||
const auto& fieldsMap = type->properties->getMap();
|
||||
const auto& fieldsMap = type->propertiesGetter()->getMap();
|
||||
|
||||
caret.skipBlankChars();
|
||||
|
||||
@ -404,7 +357,7 @@ data::mapping::type::AbstractObjectWrapper Deserializer::deserializeObject(Deser
|
||||
|
||||
}
|
||||
|
||||
data::mapping::type::AbstractObjectWrapper Deserializer::deserialize(parser::Caret& caret, const Type* const type) {
|
||||
oatpp::Void Deserializer::deserialize(parser::Caret& caret, const Type* const type) {
|
||||
auto id = type->classId.id;
|
||||
auto& method = m_methods[id];
|
||||
if(method) {
|
||||
|
@ -25,15 +25,8 @@
|
||||
#ifndef oatpp_parser_json_mapping_Deserializer_hpp
|
||||
#define oatpp_parser_json_mapping_Deserializer_hpp
|
||||
|
||||
#include "oatpp/core/data/mapping/type/ListMap.hpp"
|
||||
#include "oatpp/core/data/mapping/type/List.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Object.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Type.hpp"
|
||||
|
||||
#include "oatpp/parser/json/Utils.hpp"
|
||||
#include "oatpp/core/parser/Caret.hpp"
|
||||
|
||||
#include "oatpp/core/collection/LinkedList.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include <vector>
|
||||
@ -53,12 +46,6 @@ public:
|
||||
typedef oatpp::data::mapping::type::Object Object;
|
||||
typedef oatpp::String String;
|
||||
|
||||
template<class T>
|
||||
using PolymorphicWrapper = data::mapping::type::PolymorphicWrapper<T>;
|
||||
|
||||
typedef oatpp::data::mapping::type::AbstractObjectWrapper AbstractObjectWrapper;
|
||||
typedef oatpp::data::mapping::type::List<AbstractObjectWrapper> AbstractList;
|
||||
typedef oatpp::data::mapping::type::ListMap<String, AbstractObjectWrapper> AbstractFieldsMap;
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -127,52 +114,165 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
typedef AbstractObjectWrapper (*DeserializerMethod)(Deserializer*, parser::Caret&, const Type* const);
|
||||
typedef oatpp::Void (*DeserializerMethod)(Deserializer*, parser::Caret&, const Type* const);
|
||||
private:
|
||||
static void skipScope(oatpp::parser::Caret& caret, v_char8 charOpen, v_char8 charClose);
|
||||
static void skipString(oatpp::parser::Caret& caret);
|
||||
static void skipToken(oatpp::parser::Caret& caret);
|
||||
static void skipValue(oatpp::parser::Caret& caret);
|
||||
private:
|
||||
static const Type* guessNumberType(oatpp::parser::Caret& caret);
|
||||
static const Type* guessType(oatpp::parser::Caret& caret);
|
||||
private:
|
||||
|
||||
template<class T>
|
||||
static AbstractObjectWrapper deserializeInt(Deserializer* deserializer, parser::Caret& caret, const Type* const type){
|
||||
static oatpp::Void deserializeInt(Deserializer* deserializer, parser::Caret& caret, const Type* const type){
|
||||
|
||||
(void) deserializer;
|
||||
(void) type;
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(T::Class::getType());
|
||||
return oatpp::Void(T::Class::getType());
|
||||
} else {
|
||||
return AbstractObjectWrapper(T::ObjectType::createAbstract((typename T::ObjectType::ValueType) caret.parseInt()), T::ObjectWrapper::Class::getType());
|
||||
return T(caret.parseInt());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static AbstractObjectWrapper deserializeUInt(Deserializer* deserializer, parser::Caret& caret, const Type* const type){
|
||||
static oatpp::Void deserializeUInt(Deserializer* deserializer, parser::Caret& caret, const Type* const type){
|
||||
|
||||
(void) deserializer;
|
||||
(void) type;
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return AbstractObjectWrapper(T::Class::getType());
|
||||
return oatpp::Void(T::Class::getType());
|
||||
} else {
|
||||
return AbstractObjectWrapper(T::ObjectType::createAbstract((typename T::ObjectType::ValueType) caret.parseUnsignedInt()), T::ObjectWrapper::Class::getType());
|
||||
return T(caret.parseUnsignedInt());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static AbstractObjectWrapper deserializeFloat32(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static AbstractObjectWrapper deserializeFloat64(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
template<class Collection>
|
||||
static oatpp::Void deserializeList(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
static AbstractObjectWrapper deserializeBoolean(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
if(caret.isAtText("null", true)){
|
||||
return oatpp::Void(type);
|
||||
}
|
||||
|
||||
static AbstractObjectWrapper deserializeString(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
if(caret.canContinueAtChar('[', 1)) {
|
||||
|
||||
static AbstractObjectWrapper deserializeList(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static AbstractObjectWrapper deserializeFieldsMap(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static AbstractObjectWrapper deserializeObject(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
auto listWrapper = type->creator();
|
||||
auto polymorphicDispatcher = static_cast<const typename Collection::Class::AbstractPolymorphicDispatcher*>(type->polymorphicDispatcher);
|
||||
const auto& list = listWrapper.template staticCast<Collection>();
|
||||
|
||||
Type* itemType = *type->params.begin();
|
||||
|
||||
caret.skipBlankChars();
|
||||
|
||||
while(!caret.isAtChar(']') && caret.canContinue()){
|
||||
|
||||
caret.skipBlankChars();
|
||||
auto item = deserializer->deserialize(caret, itemType);
|
||||
if(caret.hasError()){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(listWrapper, item);
|
||||
caret.skipBlankChars();
|
||||
|
||||
caret.canContinueAtChar(',', 1);
|
||||
|
||||
}
|
||||
|
||||
if(!caret.canContinueAtChar(']', 1)){
|
||||
if(!caret.hasError()){
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::deserializeList()]: Error. ']' - expected", ERROR_CODE_ARRAY_SCOPE_CLOSE);
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
return oatpp::Void(list.getPtr(), list.valueType);
|
||||
} else {
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::deserializeList()]: Error. '[' - expected", ERROR_CODE_ARRAY_SCOPE_OPEN);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class Collection>
|
||||
static oatpp::Void deserializeKeyValue(Deserializer* deserializer, parser::Caret& caret, const Type* const type) {
|
||||
|
||||
if(caret.isAtText("null", true)){
|
||||
return oatpp::Void(type);
|
||||
}
|
||||
|
||||
if(caret.canContinueAtChar('{', 1)) {
|
||||
|
||||
auto mapWrapper = type->creator();
|
||||
auto polymorphicDispatcher = static_cast<const typename Collection::Class::AbstractPolymorphicDispatcher*>(type->polymorphicDispatcher);
|
||||
const auto& map = mapWrapper.template staticCast<Collection>();
|
||||
|
||||
auto it = type->params.begin();
|
||||
Type* keyType = *it ++;
|
||||
if(keyType->classId.id != oatpp::data::mapping::type::__class::String::CLASS_ID.id){
|
||||
throw std::runtime_error("[oatpp::parser::json::mapping::Deserializer::deserializeKeyValue()]: Invalid json map key. Key should be String");
|
||||
}
|
||||
Type* valueType = *it;
|
||||
|
||||
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::parser::json::mapping::Deserializer::deserializeKeyValue()]: Error. ':' - expected", ERROR_CODE_OBJECT_SCOPE_COLON_MISSING);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
caret.skipBlankChars();
|
||||
|
||||
auto item = deserializer->deserialize(caret, valueType);
|
||||
if(caret.hasError()){
|
||||
return nullptr;
|
||||
}
|
||||
polymorphicDispatcher->addPolymorphicItem(mapWrapper, key, item);
|
||||
|
||||
caret.skipBlankChars();
|
||||
caret.canContinueAtChar(',', 1);
|
||||
|
||||
}
|
||||
|
||||
if(!caret.canContinueAtChar('}', 1)){
|
||||
if(!caret.hasError()){
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::deserializeKeyValue()]: Error. '}' - expected", ERROR_CODE_OBJECT_SCOPE_CLOSE);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return oatpp::Void(map.getPtr(), map.valueType);
|
||||
|
||||
} else {
|
||||
caret.setError("[oatpp::parser::json::mapping::Deserializer::deserializeKeyValue()]: Error. '{' - expected", ERROR_CODE_OBJECT_SCOPE_OPEN);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
static oatpp::Void deserializeFloat32(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static oatpp::Void deserializeFloat64(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static oatpp::Void deserializeBoolean(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static oatpp::Void deserializeString(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static oatpp::Void deserializeAny(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static oatpp::Void deserializeEnum(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
static oatpp::Void deserializeObject(Deserializer* deserializer, parser::Caret& caret, const Type* const type);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Config> m_config;
|
||||
@ -188,7 +288,7 @@ public:
|
||||
/**
|
||||
* Set deserializer method for type.
|
||||
* @param classId - &id:oatpp::data::mapping::type::ClassId;.
|
||||
* @param method - `typedef AbstractObjectWrapper (*DeserializerMethod)(Deserializer*, parser::Caret&, const Type* const)`.
|
||||
* @param method - `typedef oatpp::Void (*DeserializerMethod)(Deserializer*, parser::Caret&, const Type* const)`.
|
||||
*/
|
||||
void setDeserializerMethod(const data::mapping::type::ClassId& classId, DeserializerMethod method);
|
||||
|
||||
@ -196,9 +296,9 @@ public:
|
||||
* Deserialize text.
|
||||
* @param caret - &id:oatpp::parser::Caret;.
|
||||
* @param type - &id:oatpp::data::mapping::type::Type;
|
||||
* @return - `AbstractObjectWrapper` over deserialized object.
|
||||
* @return - `oatpp::Void` over deserialized object.
|
||||
*/
|
||||
AbstractObjectWrapper deserialize(parser::Caret& caret, const Type* const type);
|
||||
oatpp::Void deserialize(parser::Caret& caret, const Type* const type);
|
||||
|
||||
/**
|
||||
* Get deserializer config.
|
||||
|
@ -51,11 +51,11 @@ std::shared_ptr<ObjectMapper> ObjectMapper::createShared(const std::shared_ptr<S
|
||||
}
|
||||
|
||||
void ObjectMapper::write(data::stream::ConsistentOutputStream* stream,
|
||||
const oatpp::data::mapping::type::AbstractObjectWrapper& variant) const {
|
||||
const oatpp::Void& variant) const {
|
||||
m_serializer->serializeToStream(stream, variant);
|
||||
}
|
||||
|
||||
oatpp::data::mapping::type::AbstractObjectWrapper ObjectMapper::read(oatpp::parser::Caret& caret,
|
||||
oatpp::Void ObjectMapper::read(oatpp::parser::Caret& caret,
|
||||
const oatpp::data::mapping::type::Type* const type) const {
|
||||
return m_deserializer->deserialize(caret, type);
|
||||
}
|
||||
|
@ -87,19 +87,17 @@ public:
|
||||
/**
|
||||
* 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::data::mapping::type::AbstractObjectWrapper;.
|
||||
* @param variant - object to serialize &id:oatpp::Void;.
|
||||
*/
|
||||
void write(data::stream::ConsistentOutputStream* stream,
|
||||
const oatpp::data::mapping::type::AbstractObjectWrapper& variant) const override;
|
||||
void write(data::stream::ConsistentOutputStream* stream, const oatpp::Void& variant) const override;
|
||||
|
||||
/**
|
||||
* Implementation of &id:oatpp::data::mapping::ObjectMapper::read;.
|
||||
* @param caret - &id:oatpp::parser::Caret;.
|
||||
* @param type - type of resultant object &id:oatpp::data::mapping::type::Type;.
|
||||
* @return - &id:oatpp::data::mapping::type::AbstractObjectWrapper; holding resultant object.
|
||||
* @return - &id:oatpp::Void; holding resultant object.
|
||||
*/
|
||||
oatpp::data::mapping::type::AbstractObjectWrapper read(oatpp::parser::Caret& caret,
|
||||
const oatpp::data::mapping::type::Type* const type) const override;
|
||||
oatpp::Void read(oatpp::parser::Caret& caret, const oatpp::data::mapping::type::Type* const type) const override;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "Serializer.hpp"
|
||||
|
||||
#include "oatpp/parser/json/Utils.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Any.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
@ -34,27 +35,34 @@ Serializer::Serializer(const std::shared_ptr<Config>& config)
|
||||
|
||||
m_methods.resize(data::mapping::type::ClassId::getClassCount(), nullptr);
|
||||
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::String::CLASS_ID, &Serializer::serializeString);
|
||||
setSerializerMethod(data::mapping::type::__class::String::CLASS_ID, &Serializer::serializeString);
|
||||
setSerializerMethod(data::mapping::type::__class::Any::CLASS_ID, &Serializer::serializeAny);
|
||||
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::Int8::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int8>);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::UInt8::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt8>);
|
||||
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(oatpp::data::mapping::type::__class::Int16::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int16>);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::UInt16::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt16>);
|
||||
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(oatpp::data::mapping::type::__class::Int32::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int32>);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::UInt32::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt32>);
|
||||
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(oatpp::data::mapping::type::__class::Int64::CLASS_ID, &Serializer::serializePrimitive<oatpp::Int64>);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::UInt64::CLASS_ID, &Serializer::serializePrimitive<oatpp::UInt64>);
|
||||
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(oatpp::data::mapping::type::__class::Float32::CLASS_ID, &Serializer::serializePrimitive<oatpp::Float32>);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::Float64::CLASS_ID, &Serializer::serializePrimitive<oatpp::Float64>);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::Boolean::CLASS_ID, &Serializer::serializePrimitive<oatpp::Boolean>);
|
||||
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(oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID, &Serializer::serializeObject);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeList);
|
||||
setSerializerMethod(oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID, &Serializer::serializeFieldsMap);
|
||||
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::serializeList<oatpp::AbstractVector>);
|
||||
setSerializerMethod(data::mapping::type::__class::AbstractList::CLASS_ID, &Serializer::serializeList<oatpp::AbstractList>);
|
||||
setSerializerMethod(data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID, &Serializer::serializeList<oatpp::AbstractUnorderedSet>);
|
||||
|
||||
setSerializerMethod(data::mapping::type::__class::AbstractPairList::CLASS_ID, &Serializer::serializeKeyValue<oatpp::AbstractFields>);
|
||||
setSerializerMethod(data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID, &Serializer::serializeKeyValue<oatpp::AbstractUnorderedFields>);
|
||||
|
||||
}
|
||||
|
||||
@ -67,7 +75,7 @@ void Serializer::setSerializerMethod(const data::mapping::type::ClassId& classId
|
||||
}
|
||||
}
|
||||
|
||||
void Serializer::serializeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size) {
|
||||
void Serializer::serializeString(data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size) {
|
||||
auto encodedValue = Utils::escapeString(data, size, false);
|
||||
stream->writeCharSimple('\"');
|
||||
stream->writeSimple(encodedValue);
|
||||
@ -76,7 +84,7 @@ void Serializer::serializeString(oatpp::data::stream::ConsistentOutputStream* st
|
||||
|
||||
void Serializer::serializeString(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph)
|
||||
const oatpp::Void& polymorph)
|
||||
{
|
||||
|
||||
(void) serializer;
|
||||
@ -92,9 +100,9 @@ void Serializer::serializeString(Serializer* serializer,
|
||||
|
||||
}
|
||||
|
||||
void Serializer::serializeList(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph)
|
||||
void Serializer::serializeAny(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const oatpp::Void& polymorph)
|
||||
{
|
||||
|
||||
if(!polymorph) {
|
||||
@ -102,60 +110,38 @@ void Serializer::serializeList(Serializer* serializer,
|
||||
return;
|
||||
}
|
||||
|
||||
auto* list = static_cast<AbstractList*>(polymorph.get());
|
||||
|
||||
stream->writeCharSimple('[');
|
||||
bool first = true;
|
||||
auto curr = list->getFirstNode();
|
||||
|
||||
while(curr != nullptr){
|
||||
auto value = curr->getData();
|
||||
if(value || serializer->getConfig()->includeNullFields) {
|
||||
(first) ? first = false : stream->writeSimple(",", 1);
|
||||
serializer->serialize(stream, curr->getData());
|
||||
}
|
||||
curr = curr->getNext();
|
||||
}
|
||||
|
||||
stream->writeCharSimple(']');
|
||||
auto anyHandle = static_cast<data::mapping::type::AnyHandle*>(polymorph.get());
|
||||
serializer->serialize(stream, oatpp::Void(anyHandle->ptr, anyHandle->type));
|
||||
|
||||
}
|
||||
|
||||
void Serializer::serializeFieldsMap(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph)
|
||||
void Serializer::serializeEnum(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const oatpp::Void& polymorph)
|
||||
{
|
||||
auto polymorphicDispatcher = static_cast<const data::mapping::type::__class::AbstractEnum::AbstractPolymorphicDispatcher*>(
|
||||
polymorph.valueType->polymorphicDispatcher
|
||||
);
|
||||
|
||||
if(!polymorph) {
|
||||
stream->writeSimple("null", 4);
|
||||
data::mapping::type::EnumInterpreterError e = data::mapping::type::EnumInterpreterError::OK;
|
||||
serializer->serialize(stream, polymorphicDispatcher->toInterpretation(polymorph, e));
|
||||
|
||||
if(e == data::mapping::type::EnumInterpreterError::OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto map = static_cast<AbstractFieldsMap*>(polymorph.get());
|
||||
|
||||
stream->writeCharSimple('{');
|
||||
bool first = true;
|
||||
auto curr = map->getFirstEntry();
|
||||
|
||||
while(curr != nullptr){
|
||||
auto value = curr->getValue();
|
||||
if(value || serializer->getConfig()->includeNullFields) {
|
||||
(first) ? first = false : stream->writeSimple(",", 1);
|
||||
auto key = curr->getKey();
|
||||
serializeString(stream, key->getData(), key->getSize());
|
||||
stream->writeSimple(":", 1);
|
||||
serializer->serialize(stream, curr->getValue());
|
||||
}
|
||||
curr = curr->getNext();
|
||||
switch(e) {
|
||||
case data::mapping::type::EnumInterpreterError::CONSTRAINT_NOT_NULL:
|
||||
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serializeEnum()]: Error. Enum constraint violated - 'NotNull'.");
|
||||
default:
|
||||
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serializeEnum()]: Error. Can't serialize Enum.");
|
||||
}
|
||||
|
||||
stream->writeCharSimple('}');
|
||||
|
||||
}
|
||||
|
||||
void Serializer::serializeObject(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph)
|
||||
const oatpp::Void& polymorph)
|
||||
{
|
||||
|
||||
if(!polymorph) {
|
||||
@ -166,7 +152,7 @@ void Serializer::serializeObject(Serializer* serializer,
|
||||
stream->writeCharSimple('{');
|
||||
|
||||
bool first = true;
|
||||
auto fields = polymorph.valueType->properties->getList();
|
||||
auto fields = polymorph.valueType->propertiesGetter()->getList();
|
||||
Object* object = static_cast<Object*>(polymorph.get());
|
||||
|
||||
for (auto const& field : fields) {
|
||||
@ -186,7 +172,7 @@ void Serializer::serializeObject(Serializer* serializer,
|
||||
}
|
||||
|
||||
void Serializer::serialize(data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph)
|
||||
const oatpp::Void& polymorph)
|
||||
{
|
||||
auto id = polymorph.valueType->classId.id;
|
||||
auto& method = m_methods[id];
|
||||
@ -199,7 +185,7 @@ void Serializer::serialize(data::stream::ConsistentOutputStream* stream,
|
||||
}
|
||||
|
||||
void Serializer::serializeToStream(data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph)
|
||||
const oatpp::Void& polymorph)
|
||||
{
|
||||
if(m_config->useBeautifier) {
|
||||
json::Beautifier beautifier(stream, " ", "\n");
|
||||
|
@ -26,16 +26,7 @@
|
||||
#define oatpp_parser_json_mapping_Serializer_hpp
|
||||
|
||||
#include "oatpp/parser/json/Beautifier.hpp"
|
||||
|
||||
#include "oatpp/core/data/mapping/type/ListMap.hpp"
|
||||
#include "oatpp/core/data/mapping/type/List.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Object.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Type.hpp"
|
||||
|
||||
#include "oatpp/core/collection/LinkedList.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
@ -52,14 +43,6 @@ public:
|
||||
|
||||
typedef oatpp::data::mapping::type::Object Object;
|
||||
typedef oatpp::String String;
|
||||
|
||||
template<class T>
|
||||
using PolymorphicWrapper = data::mapping::type::PolymorphicWrapper<T>;
|
||||
|
||||
typedef oatpp::data::mapping::type::AbstractObjectWrapper AbstractObjectWrapper;
|
||||
typedef oatpp::data::mapping::type::List<AbstractObjectWrapper> AbstractList;
|
||||
typedef oatpp::data::mapping::type::ListMap<String, AbstractObjectWrapper> AbstractFieldsMap;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Serializer config.
|
||||
@ -113,40 +96,92 @@ public:
|
||||
public:
|
||||
typedef void (*SerializerMethod)(Serializer*,
|
||||
data::stream::ConsistentOutputStream*,
|
||||
const data::mapping::type::AbstractObjectWrapper&);
|
||||
const oatpp::Void&);
|
||||
private:
|
||||
|
||||
template<class T>
|
||||
static void serializePrimitive(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph){
|
||||
const oatpp::Void& polymorph){
|
||||
(void) serializer;
|
||||
|
||||
if(polymorph){
|
||||
stream->writeAsString(static_cast<typename T::ObjectType*>(polymorph.get())->getValue());
|
||||
stream->writeAsString(* static_cast<typename T::ObjectType*>(polymorph.get()));
|
||||
} else {
|
||||
stream->writeSimple("null", 4);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Collection>
|
||||
static void serializeList(Serializer* serializer, data::stream::ConsistentOutputStream* stream, const oatpp::Void& polymorph) {
|
||||
|
||||
if(!polymorph) {
|
||||
stream->writeSimple("null", 4);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& list = polymorph.staticCast<Collection>();
|
||||
|
||||
stream->writeCharSimple('[');
|
||||
bool first = true;
|
||||
|
||||
for(auto& value : *list) {
|
||||
if(value || serializer->getConfig()->includeNullFields) {
|
||||
(first) ? first = false : stream->writeSimple(",", 1);
|
||||
serializer->serialize(stream, value);
|
||||
}
|
||||
}
|
||||
|
||||
stream->writeCharSimple(']');
|
||||
|
||||
}
|
||||
|
||||
template<class Collection>
|
||||
static void serializeKeyValue(Serializer* serializer, data::stream::ConsistentOutputStream* stream, const oatpp::Void& polymorph) {
|
||||
|
||||
if(!polymorph) {
|
||||
stream->writeSimple("null", 4);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& map = polymorph.staticCast<Collection>();
|
||||
|
||||
stream->writeCharSimple('{');
|
||||
bool first = true;
|
||||
|
||||
for(auto& pair : *map) {
|
||||
const auto& value = pair.second;
|
||||
if(value || serializer->getConfig()->includeNullFields) {
|
||||
(first) ? first = false : stream->writeSimple(",", 1);
|
||||
const auto& key = pair.first;
|
||||
serializeString(stream, key->getData(), key->getSize());
|
||||
stream->writeSimple(":", 1);
|
||||
serializer->serialize(stream, value);
|
||||
}
|
||||
}
|
||||
|
||||
stream->writeCharSimple('}');
|
||||
|
||||
}
|
||||
|
||||
static void serializeString(oatpp::data::stream::ConsistentOutputStream* stream, p_char8 data, v_buff_size size);
|
||||
static void serializeString(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph);
|
||||
const oatpp::Void& polymorph);
|
||||
|
||||
static void serializeList(Serializer* serializer,
|
||||
static void serializeAny(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const oatpp::Void& polymorph);
|
||||
|
||||
static void serializeEnum(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph);
|
||||
|
||||
static void serializeFieldsMap(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph);
|
||||
const oatpp::Void& polymorph);
|
||||
|
||||
static void serializeObject(Serializer* serializer,
|
||||
data::stream::ConsistentOutputStream* stream,
|
||||
const data::mapping::type::AbstractObjectWrapper& polymorph);
|
||||
const oatpp::Void& polymorph);
|
||||
|
||||
void serialize(data::stream::ConsistentOutputStream* stream, const data::mapping::type::AbstractObjectWrapper& polymorph);
|
||||
void serialize(data::stream::ConsistentOutputStream* stream, const oatpp::Void& polymorph);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Config> m_config;
|
||||
@ -162,16 +197,16 @@ public:
|
||||
/**
|
||||
* Set serializer method for type.
|
||||
* @param classId - &id:oatpp::data::mapping::type::ClassId;.
|
||||
* @param method - `typedef void (*SerializerMethod)(Serializer*, data::stream::ConsistentOutputStream*, const data::mapping::type::AbstractObjectWrapper&)`.
|
||||
* @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::data::mapping::type::AbstractObjectWrapper;.
|
||||
* @param polymorph - DTO as &id:oatpp::Void;.
|
||||
*/
|
||||
void serializeToStream(data::stream::ConsistentOutputStream* stream, const data::mapping::type::AbstractObjectWrapper& polymorph);
|
||||
void serializeToStream(data::stream::ConsistentOutputStream* stream, const oatpp::Void& polymorph);
|
||||
|
||||
/**
|
||||
* Get serializer config.
|
||||
|
@ -84,7 +84,7 @@ void ApiClient::formatPath(oatpp::data::stream::ConsistentOutputStream* stream,
|
||||
auto& param = params->get(key, nullptr);
|
||||
if(!param){
|
||||
OATPP_LOGD(TAG, "Path parameter '%s' not provided in the api call", seg.text.c_str());
|
||||
throw std::runtime_error("[oatpp::web::client::ApiClient]: Path parameter missing");
|
||||
throw std::runtime_error("[oatpp::web::client::ApiClient::formatPath()]: Path parameter missing");
|
||||
}
|
||||
stream->data::stream::OutputStream::writeSimple(param);
|
||||
}
|
||||
@ -132,7 +132,12 @@ web::protocol::http::Headers ApiClient::mapToHeaders(const std::shared_ptr<Strin
|
||||
auto curr = params->getFirstEntry();
|
||||
|
||||
while (curr != nullptr) {
|
||||
result.put_LockFree(curr->getKey(), curr->getValue());
|
||||
if(curr->getValue()) {
|
||||
result.put_LockFree(curr->getKey(), curr->getValue());
|
||||
} else {
|
||||
OATPP_LOGE(TAG, "Header parameter '%s' not provided in the api call", curr->getKey()->c_str());
|
||||
throw std::runtime_error("[oatpp::web::client::ApiClient::mapToHeaders()]: Header parameter missing");
|
||||
}
|
||||
curr = curr->getNext();
|
||||
}
|
||||
}
|
||||
|
@ -73,35 +73,69 @@ public:
|
||||
*/
|
||||
typedef oatpp::web::protocol::http::Header Header;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::String;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::String String;
|
||||
typedef oatpp::String String;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int8;.
|
||||
*/
|
||||
typedef oatpp::Int8 Int8;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt8;.
|
||||
*/
|
||||
typedef oatpp::UInt8 UInt8;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int16;.
|
||||
*/
|
||||
typedef oatpp::Int16 Int16;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt16;.
|
||||
*/
|
||||
typedef oatpp::UInt16 UInt16;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int32;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Int32 Int32;
|
||||
typedef oatpp::Int32 Int32;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt32;.
|
||||
*/
|
||||
typedef oatpp::UInt32 UInt32;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int64;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Int64 Int64;
|
||||
typedef oatpp::Int64 Int64;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt64;.
|
||||
*/
|
||||
typedef oatpp::UInt64 UInt64;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Float32;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Float32 Float32;
|
||||
typedef oatpp::Float32 Float32;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Float64;.
|
||||
* Convenience typedef for &id:atpp::data::mapping::type::Float64;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Float64 Float64;
|
||||
typedef oatpp::Float64 Float64;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Boolean;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Boolean Boolean;
|
||||
typedef oatpp::Boolean Boolean;
|
||||
|
||||
template <class T>
|
||||
using Enum = oatpp::data::mapping::type::Enum<T>;
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -209,123 +243,184 @@ public:
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
oatpp::String convertParameterToString(const oatpp::String& typeName, const T& parameter) {
|
||||
struct TypeInterpretation {
|
||||
|
||||
(void) parameter;
|
||||
static oatpp::String toString(const oatpp::String& typeName, const T& parameter) {
|
||||
|
||||
OATPP_LOGE("[oatpp::web::client::ApiClient::convertParameterToString()]",
|
||||
"Error. No conversion from '%s' to '%s' is defined.", typeName->getData(), "oatpp::String");
|
||||
throw std::runtime_error("[oatpp::web::client::ApiClient::convertParameterToString()]: Error. "
|
||||
"No conversion from '" + typeName->std_str() + "' to 'oatpp::String' is defined. "
|
||||
"Please define type conversion.");
|
||||
}
|
||||
(void) parameter;
|
||||
|
||||
OATPP_LOGE("[oatpp::web::client::ApiClient::TypeInterpretation::toString()]",
|
||||
"Error. No conversion from '%s' to '%s' is defined.", typeName->getData(), "oatpp::String");
|
||||
|
||||
throw std::runtime_error(
|
||||
"[oatpp::web::client::ApiClient::TypeInterpretation::toString()]: Error. "
|
||||
"No conversion from '" + typeName->std_str() + "' to 'oatpp::String' is defined. "
|
||||
"Please define type conversion."
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::String& parameter) {
|
||||
(void) typeName;
|
||||
return parameter;
|
||||
}
|
||||
struct ApiClient::TypeInterpretation<oatpp::String> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::String ¶meter) {
|
||||
(void) typeName;
|
||||
return parameter;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Int8& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::int32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Int8> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Int8 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::int32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::UInt8& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::uint32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::UInt8> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::UInt8 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::uint32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Int16& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::int32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Int16> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Int16 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::int32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::UInt16& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::uint32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::UInt16> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::UInt16 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::uint32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Int32& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::int32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Int32> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Int32 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::int32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::UInt32& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::uint32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::UInt32> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::UInt32 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::uint32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Int64& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::int64ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Int64> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Int64 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::int64ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::UInt64& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::uint64ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::UInt64> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::UInt64 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::uint64ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Float32& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::float32ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Float32> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Float32 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::float32ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Float64& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::float64ToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Float64> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Float64 ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::float64ToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiClient::convertParameterToString(const oatpp::String& typeName, const oatpp::Boolean& parameter) {
|
||||
(void) typeName;
|
||||
if(parameter) {
|
||||
return utils::conversion::boolToStr(parameter->getValue());
|
||||
struct ApiClient::TypeInterpretation<oatpp::Boolean> {
|
||||
static oatpp::String toString(const oatpp::String &typeName, const oatpp::Boolean ¶meter) {
|
||||
(void) typeName;
|
||||
if (parameter) {
|
||||
return utils::conversion::boolToStr(*parameter);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return "nullptr";
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class I>
|
||||
struct ApiClient::TypeInterpretation<data::mapping::type::EnumObjectWrapper<T, I>> {
|
||||
|
||||
typedef data::mapping::type::EnumObjectWrapper<T, I> EnumOW;
|
||||
typedef typename I::UnderlyingTypeObjectWrapper UTOW;
|
||||
|
||||
static oatpp::String toString(const oatpp::String &typeName, const EnumOW ¶meter) {
|
||||
|
||||
data::mapping::type::EnumInterpreterError error = data::mapping::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:
|
||||
throw std::runtime_error(
|
||||
"[oatpp::web::client::ApiClient::TypeInterpretation::toString()]: Error. Enum constraint violation - NotNull."
|
||||
);
|
||||
default:
|
||||
throw std::runtime_error(
|
||||
"[oatpp::web::client::ApiClient::TypeInterpretation::toString()]: Error. Can't interpret Enum."
|
||||
);
|
||||
}
|
||||
|
||||
return ApiClient::TypeInterpretation<UTOW>::toString(typeName, value.template staticCast<UTOW>());
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
@ -735,7 +735,7 @@ namespace std {
|
||||
struct hash<oatpp::web::protocol::http::Status> {
|
||||
|
||||
typedef oatpp::web::protocol::http::Status argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::web::protocol::http::Status const& s) const noexcept {
|
||||
return s.code;
|
||||
|
@ -199,22 +199,9 @@ public:
|
||||
* @return DTO
|
||||
*/
|
||||
template<class Type>
|
||||
typename Type::ObjectWrapper readBodyToDto(data::mapping::ObjectMapper* objectMapper) const {
|
||||
typename Type::__Wrapper readBodyToDto(data::mapping::ObjectMapper* objectMapper) const {
|
||||
return objectMapper->readFromString<Type>(m_bodyDecoder->decodeToString(m_headers, m_bodyStream.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer body to String and parse it as DTO
|
||||
* (used in ApiController's codegens)
|
||||
* @tparam Type
|
||||
* @param objectMapper
|
||||
* @return DTO
|
||||
*/
|
||||
template<class Type>
|
||||
void readBodyToDto(data::mapping::type::PolymorphicWrapper<Type>& objectWrapper,
|
||||
data::mapping::ObjectMapper* objectMapper) const {
|
||||
objectWrapper = objectMapper->readFromString<Type>(m_bodyDecoder->decodeToString(m_headers, m_bodyStream.get()));
|
||||
}
|
||||
|
||||
// Async
|
||||
|
||||
@ -246,7 +233,7 @@ public:
|
||||
* @return - &id:oatpp::async::CoroutineStarterForResult;.
|
||||
*/
|
||||
template<class DtoType>
|
||||
oatpp::async::CoroutineStarterForResult<const typename DtoType::ObjectWrapper&>
|
||||
oatpp::async::CoroutineStarterForResult<const typename DtoType::__Wrapper&>
|
||||
readBodyToDtoAsync(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper) const {
|
||||
return m_bodyDecoder->decodeToDtoAsync<DtoType>(m_headers, m_bodyStream, objectMapper);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ ResponseFactory::createResponse(const Status& status, const oatpp::String& text)
|
||||
|
||||
std::shared_ptr<Response>
|
||||
ResponseFactory::createResponse(const Status& status,
|
||||
const data::mapping::type::AbstractObjectWrapper& dto,
|
||||
const oatpp::Void& dto,
|
||||
const std::shared_ptr<data::mapping::ObjectMapper>& objectMapper) {
|
||||
return Response::createShared(status, BufferBody::createShared(
|
||||
objectMapper->writeToString(dto),
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
* @return - `std::shared_ptr` to &id:oatpp::web::protocol::http::outgoing::Response;.
|
||||
*/
|
||||
static std::shared_ptr<Response> createResponse(const Status& status,
|
||||
const data::mapping::type::AbstractObjectWrapper& dto,
|
||||
const oatpp::Void& dto,
|
||||
const std::shared_ptr<data::mapping::ObjectMapper>& objectMapper);
|
||||
|
||||
};
|
||||
|
@ -95,13 +95,13 @@ std::shared_ptr<ApiController::OutgoingResponse> ApiController::createResponse(c
|
||||
}
|
||||
|
||||
std::shared_ptr<ApiController::OutgoingResponse> ApiController::createDtoResponse(const Status& status,
|
||||
const oatpp::data::mapping::type::AbstractObjectWrapper& dto,
|
||||
const oatpp::Void& dto,
|
||||
const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper) const {
|
||||
return ResponseFactory::createResponse(status, dto, objectMapper);
|
||||
}
|
||||
|
||||
std::shared_ptr<ApiController::OutgoingResponse> ApiController::createDtoResponse(const Status& status,
|
||||
const oatpp::data::mapping::type::AbstractObjectWrapper& dto) const {
|
||||
const oatpp::Void& dto) const {
|
||||
return ResponseFactory::createResponse(status, dto, m_defaultObjectMapper);
|
||||
}
|
||||
|
||||
|
@ -126,62 +126,62 @@ public:
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::String;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::String String;
|
||||
typedef oatpp::String String;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int8;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Int8 Int8;
|
||||
typedef oatpp::Int8 Int8;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt8;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::UInt8 UInt8;
|
||||
typedef oatpp::UInt8 UInt8;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int16;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Int16 Int16;
|
||||
typedef oatpp::Int16 Int16;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt16;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::UInt16 UInt16;
|
||||
typedef oatpp::UInt16 UInt16;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int32;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Int32 Int32;
|
||||
typedef oatpp::Int32 Int32;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt32;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::UInt32 UInt32;
|
||||
typedef oatpp::UInt32 UInt32;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Int64;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Int64 Int64;
|
||||
typedef oatpp::Int64 Int64;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::UInt64;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::UInt64 UInt64;
|
||||
typedef oatpp::UInt64 UInt64;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Float32;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Float32 Float32;
|
||||
typedef oatpp::Float32 Float32;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:atpp::data::mapping::type::Float64;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Float64 Float64;
|
||||
typedef oatpp::Float64 Float64;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::mapping::type::Boolean;.
|
||||
*/
|
||||
typedef oatpp::data::mapping::type::Boolean Boolean;
|
||||
typedef oatpp::Boolean Boolean;
|
||||
|
||||
/*
|
||||
* Convenience typedef for std::function<std::shared_ptr<Endpoint::Info>()>.
|
||||
@ -189,9 +189,13 @@ public:
|
||||
typedef std::function<std::shared_ptr<Endpoint::Info>()> EndpointInfoBuilder;
|
||||
|
||||
template <class T>
|
||||
using List = oatpp::data::mapping::type::List<T>;
|
||||
using List = oatpp::List<T>;
|
||||
|
||||
template <class Value>
|
||||
using Fields = oatpp::data::mapping::type::ListMap<String, Value>;
|
||||
using Fields = oatpp::Fields<Value>;
|
||||
|
||||
template <class T>
|
||||
using Enum = oatpp::data::mapping::type::Enum<T>;
|
||||
|
||||
protected:
|
||||
|
||||
@ -440,99 +444,148 @@ public:
|
||||
const oatpp::String& str) const;
|
||||
|
||||
std::shared_ptr<OutgoingResponse> createDtoResponse(const Status& status,
|
||||
const oatpp::data::mapping::type::AbstractObjectWrapper& dto,
|
||||
const oatpp::Void& dto,
|
||||
const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& objectMapper) const;
|
||||
|
||||
std::shared_ptr<OutgoingResponse> createDtoResponse(const Status& status,
|
||||
const oatpp::data::mapping::type::AbstractObjectWrapper& dto) const;
|
||||
const oatpp::Void& dto) const;
|
||||
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
T parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) text;
|
||||
success = false;
|
||||
OATPP_LOGE("[oatpp::web::server::api::ApiController::parseParameterFromString()]",
|
||||
"Error. No conversion from '%s' to '%s' is defined.", "oatpp::String", typeName->getData());
|
||||
throw std::runtime_error("[oatpp::web::server::api::ApiController::parseParameterFromString()]: Error. "
|
||||
"No conversion from 'oatpp::String' to '" + typeName->std_str() + "' is defined. "
|
||||
"Please define type conversion.");
|
||||
}
|
||||
struct TypeInterpretation {
|
||||
|
||||
static T fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) text;
|
||||
success = false;
|
||||
OATPP_LOGE("[oatpp::web::server::api::ApiController::TypeInterpretation::fromString()]",
|
||||
"Error. No conversion from '%s' to '%s' is defined.", "oatpp::String", typeName->getData());
|
||||
throw std::runtime_error("[oatpp::web::server::api::ApiController::TypeInterpretation::fromString()]: Error. "
|
||||
"No conversion from 'oatpp::String' to '" + typeName->std_str() + "' is defined. "
|
||||
"Please define type conversion.");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::String ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
success = true;
|
||||
return text;
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::String> {
|
||||
static oatpp::String fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
success = true;
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Int8 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Int8> {
|
||||
static oatpp::Int8 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::UInt8 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::UInt8> {
|
||||
static oatpp::UInt8 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Int16 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Int16> {
|
||||
static oatpp::Int16 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::UInt16 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::UInt16> {
|
||||
static oatpp::UInt16 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Int32 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Int32> {
|
||||
static oatpp::Int32 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::UInt32 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::UInt32> {
|
||||
static oatpp::UInt32 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Int64 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt64(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Int64> {
|
||||
static oatpp::Int64 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToInt64(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::UInt64 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt64(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::UInt64> {
|
||||
static oatpp::UInt64 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToUInt64(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Float32 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToFloat32(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Float32> {
|
||||
static oatpp::Float32 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToFloat32(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Float64 ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToFloat64(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Float64> {
|
||||
static oatpp::Float64 fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToFloat64(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline oatpp::Boolean ApiController::parseParameterFromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToBool(text, success);
|
||||
}
|
||||
struct ApiController::TypeInterpretation <oatpp::Boolean> {
|
||||
static oatpp::Boolean fromString(const oatpp::String& typeName, const oatpp::String& text, bool& success) {
|
||||
(void) typeName;
|
||||
return utils::conversion::strToBool(text, success);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class I>
|
||||
struct ApiController::TypeInterpretation <data::mapping::type::EnumObjectWrapper<T, I>> {
|
||||
|
||||
typedef data::mapping::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;
|
||||
const auto& result = I::fromInterpretation(parsedValue, error);
|
||||
if(error == data::mapping::type::EnumInterpreterError::OK) {
|
||||
return result.template staticCast<EnumOW>();
|
||||
}
|
||||
success = false;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
|
@ -96,7 +96,7 @@ public:
|
||||
*/
|
||||
template<class T>
|
||||
Param& add(const oatpp::String& name) {
|
||||
return add(name, T::Class::getType());
|
||||
return add(name, T::__Wrapper::Class::getType());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +220,7 @@ public:
|
||||
*/
|
||||
template<class T>
|
||||
void addConsumes(const oatpp::String& contentType) {
|
||||
consumes.push_back({contentType, T::Class::getType()});
|
||||
consumes.push_back({contentType, T::__Wrapper::Class::getType()});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,7 +232,7 @@ public:
|
||||
*/
|
||||
template<class T>
|
||||
void addResponse(const oatpp::web::protocol::http::Status& status, const oatpp::String& contentType, const oatpp::String& responseDescription = oatpp::String()) {
|
||||
responses[status] = {contentType, T::Class::getType(), responseDescription.get() == nullptr ? status.description : responseDescription};
|
||||
responses[status] = {contentType, T::__Wrapper::Class::getType(), responseDescription.get() == nullptr ? status.description : responseDescription};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,8 +5,6 @@ add_executable(oatppAllTests
|
||||
oatpp/core/async/LockTest.hpp
|
||||
oatpp/core/base/CommandLineArgumentsTest.cpp
|
||||
oatpp/core/base/CommandLineArgumentsTest.hpp
|
||||
oatpp/core/base/RegRuleTest.cpp
|
||||
oatpp/core/base/RegRuleTest.hpp
|
||||
oatpp/core/base/collection/LinkedListTest.cpp
|
||||
oatpp/core/base/collection/LinkedListTest.hpp
|
||||
oatpp/core/base/memory/MemoryPoolTest.cpp
|
||||
@ -15,8 +13,30 @@ add_executable(oatppAllTests
|
||||
oatpp/core/base/memory/PerfTest.hpp
|
||||
oatpp/core/data/buffer/ProcessorTest.cpp
|
||||
oatpp/core/data/buffer/ProcessorTest.hpp
|
||||
oatpp/core/data/mapping/type/AnyTest.cpp
|
||||
oatpp/core/data/mapping/type/AnyTest.hpp
|
||||
oatpp/core/data/mapping/type/EnumTest.cpp
|
||||
oatpp/core/data/mapping/type/EnumTest.hpp
|
||||
oatpp/core/data/mapping/type/ListTest.cpp
|
||||
oatpp/core/data/mapping/type/ListTest.hpp
|
||||
oatpp/core/data/mapping/type/ObjectTest.cpp
|
||||
oatpp/core/data/mapping/type/ObjectTest.hpp
|
||||
oatpp/core/data/mapping/type/ObjectWrapperTest.cpp
|
||||
oatpp/core/data/mapping/type/ObjectWrapperTest.hpp
|
||||
oatpp/core/data/mapping/type/PairListTest.cpp
|
||||
oatpp/core/data/mapping/type/PairListTest.hpp
|
||||
oatpp/core/data/mapping/type/PrimitiveTest.cpp
|
||||
oatpp/core/data/mapping/type/PrimitiveTest.hpp
|
||||
oatpp/core/data/mapping/type/StringTest.cpp
|
||||
oatpp/core/data/mapping/type/StringTest.hpp
|
||||
oatpp/core/data/mapping/type/TypeTest.cpp
|
||||
oatpp/core/data/mapping/type/TypeTest.hpp
|
||||
oatpp/core/data/mapping/type/UnorderedMapTest.cpp
|
||||
oatpp/core/data/mapping/type/UnorderedMapTest.hpp
|
||||
oatpp/core/data/mapping/type/UnorderedSetTest.cpp
|
||||
oatpp/core/data/mapping/type/UnorderedSetTest.hpp
|
||||
oatpp/core/data/mapping/type/VectorTest.cpp
|
||||
oatpp/core/data/mapping/type/VectorTest.hpp
|
||||
oatpp/core/data/share/LazyStringMapTest.cpp
|
||||
oatpp/core/data/share/LazyStringMapTest.hpp
|
||||
oatpp/core/data/share/MemoryLabelTest.cpp
|
||||
@ -45,6 +65,10 @@ add_executable(oatppAllTests
|
||||
oatpp/parser/json/mapping/DTOMapperTest.hpp
|
||||
oatpp/parser/json/mapping/DeserializerTest.cpp
|
||||
oatpp/parser/json/mapping/DeserializerTest.hpp
|
||||
oatpp/parser/json/mapping/EnumTest.cpp
|
||||
oatpp/parser/json/mapping/EnumTest.hpp
|
||||
oatpp/parser/json/mapping/UnorderedSetTest.cpp
|
||||
oatpp/parser/json/mapping/UnorderedSetTest.hpp
|
||||
oatpp/web/protocol/http/encoding/ChunkedTest.cpp
|
||||
oatpp/web/protocol/http/encoding/ChunkedTest.hpp
|
||||
oatpp/web/mime/multipart/StatefulParserTest.cpp
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "oatpp/parser/json/mapping/DeserializerTest.hpp"
|
||||
#include "oatpp/parser/json/mapping/DTOMapperPerfTest.hpp"
|
||||
#include "oatpp/parser/json/mapping/DTOMapperTest.hpp"
|
||||
#include "oatpp/parser/json/mapping/EnumTest.hpp"
|
||||
#include "oatpp/parser/json/mapping/UnorderedSetTest.hpp"
|
||||
|
||||
#include "oatpp/encoding/UnicodeTest.hpp"
|
||||
#include "oatpp/encoding/Base64Test.hpp"
|
||||
@ -38,12 +40,23 @@
|
||||
|
||||
#include "oatpp/core/parser/CaretTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/mapping/type/UnorderedMapTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/PairListTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/VectorTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/UnorderedSetTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/ListTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/ObjectTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/StringTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/PrimitiveTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/ObjectWrapperTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/TypeTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/AnyTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/EnumTest.hpp"
|
||||
|
||||
#include "oatpp/core/base/collection/LinkedListTest.hpp"
|
||||
#include "oatpp/core/base/memory/MemoryPoolTest.hpp"
|
||||
#include "oatpp/core/base/memory/PerfTest.hpp"
|
||||
#include "oatpp/core/base/CommandLineArgumentsTest.hpp"
|
||||
#include "oatpp/core/base/RegRuleTest.hpp"
|
||||
|
||||
#include "oatpp/core/async/Coroutine.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
@ -64,7 +77,6 @@ void runTests() {
|
||||
OATPP_LOGD("aaa", "coroutine size=%d", sizeof(oatpp::async::AbstractCoroutine));
|
||||
OATPP_LOGD("aaa", "action size=%d", sizeof(oatpp::async::Action));
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::base::RegRuleTest);
|
||||
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::memory::MemoryPoolTest);
|
||||
@ -81,15 +93,30 @@ void runTests() {
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::stream::ChunkedBufferTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::stream::BufferStreamTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::ObjectWrapperTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::TypeTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::StringTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::PrimitiveTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::ListTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::VectorTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::UnorderedSetTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::PairListTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::UnorderedMapTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::AnyTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::EnumTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::ObjectTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::async::LockTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::CaretTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::EnumTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::UnorderedSetTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DeserializerTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DTOMapperPerfTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DTOMapperTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::encoding::Base64Test);
|
||||
|
@ -1,158 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "RegRuleTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace oatpp { namespace test { namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
class BaseClass : public oatpp::base::Countable {
|
||||
public:
|
||||
|
||||
template<class T>
|
||||
static T create1() {
|
||||
return new BaseClass();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static T create2() {
|
||||
return T(new BaseClass());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ChildClass : public BaseClass {
|
||||
public:
|
||||
|
||||
template<class T>
|
||||
static T create1() {
|
||||
return new ChildClass();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static T create2() {
|
||||
return T(new ChildClass());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef oatpp::String String;
|
||||
|
||||
template<typename T>
|
||||
using ObjectWrapper = oatpp::data::mapping::type::PolymorphicWrapper<T>;
|
||||
|
||||
template<typename T>
|
||||
using PolymorphicWrapper = oatpp::data::mapping::type::PolymorphicWrapper<T>;
|
||||
|
||||
template<typename T>
|
||||
using TypeObjectWrapper = oatpp::data::mapping::type::ObjectWrapper<T, oatpp::data::mapping::type::__class::Void>;
|
||||
|
||||
typedef oatpp::data::mapping::type::Int32 Int32;
|
||||
typedef oatpp::data::mapping::type::Int64 Int64;
|
||||
typedef oatpp::data::mapping::type::Float32 Float32;
|
||||
typedef oatpp::data::mapping::type::Float64 Float64;
|
||||
typedef oatpp::data::mapping::type::Boolean Boolean;
|
||||
|
||||
}
|
||||
|
||||
void RegRuleTest::onRun() {
|
||||
|
||||
{
|
||||
String reg1("");
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
String reg4 = String(100);
|
||||
}
|
||||
|
||||
{
|
||||
String reg1("");
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
String reg4 = String(100) + "Leonid";
|
||||
}
|
||||
|
||||
{
|
||||
String reg1 = String(100);
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
}
|
||||
|
||||
{
|
||||
String reg1(String(100) + "Leonid");
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
String reg4 = String(100);
|
||||
}
|
||||
|
||||
{
|
||||
String reg1 = String(100);
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
}
|
||||
|
||||
{
|
||||
String reg1 = String(100);
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
}
|
||||
|
||||
{
|
||||
String reg1 = String(100);
|
||||
String reg2(reg1);
|
||||
OATPP_ASSERT(reg1);
|
||||
String reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1);
|
||||
}
|
||||
|
||||
std::unordered_map<String, String> map;
|
||||
|
||||
map["str_1"] = "val_1";
|
||||
map["str_2"] = "val_2";
|
||||
map["str_3"] = "val_3";
|
||||
|
||||
OATPP_ASSERT(map.find("str_1")->second == "val_1");
|
||||
OATPP_ASSERT(map.find("str_2")->second == "val_2");
|
||||
OATPP_ASSERT(map.find("str_3")->second == "val_3");
|
||||
|
||||
}
|
||||
|
||||
}}}
|
183
test/oatpp/core/data/mapping/type/AnyTest.cpp
Normal file
183
test/oatpp/core/data/mapping/type/AnyTest.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "AnyTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/mapping/type/Any.hpp"
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class Dto1 : public oatpp::Object {
|
||||
DTO_INIT(Dto1, Object);
|
||||
};
|
||||
|
||||
class Dto2 : public oatpp::Object {
|
||||
DTO_INIT(Dto2, Object);
|
||||
};
|
||||
|
||||
class Test : public oatpp::Object {
|
||||
|
||||
DTO_INIT(Test, Object);
|
||||
|
||||
DTO_FIELD(oatpp::Any, any);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
void AnyTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test default constructor...");
|
||||
oatpp::Any any;
|
||||
OATPP_ASSERT(!any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == nullptr);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test nullptr constructor...");
|
||||
oatpp::Any any(nullptr);
|
||||
OATPP_ASSERT(!any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == nullptr);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test retrieve()...");
|
||||
oatpp::Any any(oatpp::String("Hello Any!"));
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
auto str = any.retrieve<oatpp::String>();
|
||||
OATPP_ASSERT(str == "Hello Any!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test store()...");
|
||||
oatpp::Any any(oatpp::Int32(32));
|
||||
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::Int32::getType());
|
||||
|
||||
any.store(oatpp::String("Hello Any!"));
|
||||
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
auto str = any.retrieve<oatpp::String>();
|
||||
OATPP_ASSERT(str == "Hello Any!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test retrieve() class check...");
|
||||
oatpp::Any any(Dto1::createShared());
|
||||
OATPP_ASSERT(any);
|
||||
OATPP_ASSERT(any.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any.getStoredType() == Dto1::ObjectWrapper::Class::getType());
|
||||
|
||||
bool wasError = false;
|
||||
|
||||
try {
|
||||
auto obj = any.retrieve<Dto2>(); // wrong object
|
||||
} catch (std::runtime_error& e) {
|
||||
wasError = true;
|
||||
}
|
||||
|
||||
OATPP_ASSERT(wasError);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test copy-assign operator...");
|
||||
oatpp::Any any1(oatpp::String("Hello!"));
|
||||
oatpp::Any any2;
|
||||
|
||||
any2 = any1;
|
||||
|
||||
OATPP_ASSERT(any1);
|
||||
OATPP_ASSERT(any2);
|
||||
|
||||
OATPP_ASSERT(any1.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any2.valueType == oatpp::data::mapping::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 == any2);
|
||||
OATPP_ASSERT(any1.getPtr().get() != any2.getPtr().get());
|
||||
|
||||
auto str1 = any1.retrieve<oatpp::String>();
|
||||
auto str2 = any2.retrieve<oatpp::String>();
|
||||
|
||||
OATPP_ASSERT(str1 == str2);
|
||||
OATPP_ASSERT(str1.get() == str2.get() && str1 == "Hello!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test move-assign operator...");
|
||||
oatpp::Any any1(oatpp::String("Hello!"));
|
||||
oatpp::Any any2;
|
||||
|
||||
any2 = std::move(any1);
|
||||
|
||||
OATPP_ASSERT(!any1);
|
||||
OATPP_ASSERT(any2);
|
||||
|
||||
OATPP_ASSERT(any1.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
OATPP_ASSERT(any2.valueType == oatpp::data::mapping::type::__class::Any::getType());
|
||||
|
||||
OATPP_ASSERT(any1.getStoredType() == nullptr);
|
||||
OATPP_ASSERT(any2.getStoredType() == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
OATPP_ASSERT(any1 != any2);
|
||||
OATPP_ASSERT(any1.getPtr().get() != any2.getPtr().get());
|
||||
|
||||
auto str1 = any1.retrieve<oatpp::String>();
|
||||
auto str2 = any2.retrieve<oatpp::String>();
|
||||
|
||||
OATPP_ASSERT(str1 != str2);
|
||||
OATPP_ASSERT(str2 == "Hello!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/AnyTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/AnyTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_AnyTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_AnyTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class AnyTest : public UnitTest{
|
||||
public:
|
||||
|
||||
AnyTest():UnitTest("TEST[core::data::mapping::type::AnyTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_AnyTest_hpp */
|
300
test/oatpp/core/data/mapping/type/EnumTest.cpp
Normal file
300
test/oatpp/core/data/mapping/type/EnumTest.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "EnumTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
ENUM(Enum0, v_int32)
|
||||
|
||||
ENUM(Enum1, v_int32,
|
||||
VALUE(V1, 1),
|
||||
VALUE(V2, 2),
|
||||
VALUE(V3, 3)
|
||||
)
|
||||
|
||||
ENUM(Enum2, v_int32,
|
||||
VALUE(NAME_1, 1, "name-1"),
|
||||
VALUE(NAME_2, 2, "name-2"),
|
||||
VALUE(NAME_3, 3, "name-3")
|
||||
)
|
||||
|
||||
ENUM(Enum3, v_int32,
|
||||
VALUE(V_1, 1, "v-1", "description_1"),
|
||||
VALUE(V_2, 2, "v-2", "description_2"),
|
||||
VALUE(V_3, 3, "v-3", "description_3")
|
||||
)
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
void EnumTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check Hash...");
|
||||
|
||||
{
|
||||
auto v = std::hash<oatpp::Enum<Enum1>>{}(oatpp::Enum<Enum1>());
|
||||
OATPP_ASSERT(v == 0);
|
||||
}
|
||||
|
||||
{
|
||||
auto v = std::hash<oatpp::Enum<Enum1>>{}(oatpp::Enum<Enum1>(Enum1::V1));
|
||||
OATPP_ASSERT(v == 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto v = std::hash<oatpp::Enum<Enum1>>{}(oatpp::Enum<Enum1>(Enum1::V2));
|
||||
OATPP_ASSERT(v == 2);
|
||||
}
|
||||
|
||||
{
|
||||
auto v = std::hash<oatpp::Enum<Enum1>>{}(oatpp::Enum<Enum1>(Enum1::V3));
|
||||
OATPP_ASSERT(v == 3);
|
||||
}
|
||||
|
||||
std::unordered_map<oatpp::Enum<Enum1>, oatpp::String> map({
|
||||
{Enum1::V1, "v1"},
|
||||
{Enum1::V2, "v2"},
|
||||
{Enum1::V3, "v3"},
|
||||
});
|
||||
|
||||
OATPP_ASSERT(map.size() == 3);
|
||||
OATPP_ASSERT(map[Enum1::V1] == "v1");
|
||||
OATPP_ASSERT(map[Enum1::V2] == "v2");
|
||||
OATPP_ASSERT(map[Enum1::V3] == "v3");
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check Meta...");
|
||||
{
|
||||
const auto &entries = oatpp::Enum<Enum0>::getEntries();
|
||||
OATPP_ASSERT(entries.size() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
const auto &v = oatpp::Enum<Enum1>::getEntries();
|
||||
OATPP_ASSERT(v.size() == 3);
|
||||
OATPP_ASSERT(v[0].index == 0 && v[0].name == "V1" && v[0].value == Enum1::V1 && v[0].description == nullptr);
|
||||
OATPP_ASSERT(v[1].index == 1 && v[1].name == "V2" && v[1].value == Enum1::V2 && v[1].description == nullptr);
|
||||
OATPP_ASSERT(v[2].index == 2 && v[2].name == "V3" && v[2].value == Enum1::V3 && v[2].description == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
const auto &v = oatpp::Enum<Enum2>::getEntries();
|
||||
OATPP_ASSERT(v.size() == 3);
|
||||
OATPP_ASSERT(v[0].index == 0 && v[0].name == "name-1" && v[0].value == Enum2::NAME_1 && v[0].description == nullptr);
|
||||
OATPP_ASSERT(v[1].index == 1 && v[1].name == "name-2" && v[1].value == Enum2::NAME_2 && v[1].description == nullptr);
|
||||
OATPP_ASSERT(v[2].index == 2 && v[2].name == "name-3" && v[2].value == Enum2::NAME_3 && v[2].description == nullptr);
|
||||
}
|
||||
|
||||
{
|
||||
const auto &v = oatpp::Enum<Enum3>::getEntries();
|
||||
OATPP_ASSERT(v.size() == 3);
|
||||
OATPP_ASSERT(v[0].index == 0 && v[0].name == "v-1" && v[0].value == Enum3::V_1 && v[0].description == "description_1");
|
||||
OATPP_ASSERT(v[1].index == 1 && v[1].name == "v-2" && v[1].value == Enum3::V_2 && v[1].description == "description_2");
|
||||
OATPP_ASSERT(v[2].index == 2 && v[2].name == "v-3" && v[2].value == Enum3::V_3 && v[2].description == "description_3");
|
||||
}
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Declaration...");
|
||||
OATPP_ASSERT(oatpp::Enum<Enum2>::Interpreter::notNull == false);
|
||||
OATPP_ASSERT(oatpp::Enum<Enum2>::NotNull::Interpreter::notNull == true);
|
||||
|
||||
OATPP_ASSERT(oatpp::Enum<Enum2>::AsString::Interpreter::notNull == false);
|
||||
OATPP_ASSERT(oatpp::Enum<Enum2>::AsString::NotNull::Interpreter::notNull == true);
|
||||
|
||||
OATPP_ASSERT(oatpp::Enum<Enum2>::AsNumber::Interpreter::notNull == false);
|
||||
OATPP_ASSERT(oatpp::Enum<Enum2>::AsNumber::NotNull::Interpreter::notNull == true);
|
||||
|
||||
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::AbstractPolymorphicDispatcher*>(
|
||||
oatpp::Enum<Enum2>::Class::getType()->polymorphicDispatcher
|
||||
);
|
||||
|
||||
auto pd2 = static_cast<const oatpp::data::mapping::type::__class::AbstractEnum::AbstractPolymorphicDispatcher*>(
|
||||
oatpp::Enum<Enum2>::NotNull::Class::getType()->polymorphicDispatcher
|
||||
);
|
||||
|
||||
OATPP_ASSERT(pd1->notNull == false);
|
||||
OATPP_ASSERT(pd2->notNull == true);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Interpreter AsString...");
|
||||
oatpp::data::mapping::type::EnumInterpreterError e = oatpp::data::mapping::type::EnumInterpreterError::OK;
|
||||
auto inter = oatpp::Enum<Enum2>::AsString::Interpreter::toInterpretation(oatpp::Enum<Enum2>::AsString(Enum2::NAME_1), e);
|
||||
OATPP_ASSERT(inter.valueType == oatpp::String::Class::getType());
|
||||
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK);
|
||||
|
||||
auto interValue = inter.staticCast<oatpp::String>();
|
||||
OATPP_ASSERT(interValue == "name-1");
|
||||
|
||||
oatpp::Void voidValue = oatpp::Enum<Enum2>::AsString::Interpreter::fromInterpretation(interValue, e);
|
||||
OATPP_ASSERT(voidValue.valueType == oatpp::Enum<Enum2>::AsString::Class::getType());
|
||||
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK);
|
||||
|
||||
auto value = voidValue.staticCast<oatpp::Enum<Enum2>::AsString>();
|
||||
OATPP_ASSERT(value == Enum2::NAME_1);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Interpreter AsNumber...");
|
||||
oatpp::data::mapping::type::EnumInterpreterError e = oatpp::data::mapping::type::EnumInterpreterError::OK;
|
||||
auto inter = oatpp::Enum<Enum2>::AsNumber::Interpreter::toInterpretation(oatpp::Enum<Enum2>::AsNumber(Enum2::NAME_1), e);
|
||||
OATPP_ASSERT(inter.valueType == oatpp::Int32::Class::getType());
|
||||
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK);
|
||||
|
||||
auto interValue = inter.staticCast<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.valueType == oatpp::Enum<Enum2>::AsNumber::Class::getType());
|
||||
OATPP_ASSERT(e == oatpp::data::mapping::type::EnumInterpreterError::OK);
|
||||
|
||||
auto value = voidValue.staticCast<oatpp::Enum<Enum2>::AsNumber>();
|
||||
OATPP_ASSERT(value == Enum2::NAME_1);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test default constructors and == operators...");
|
||||
oatpp::Enum<Enum2>::AsString e1;
|
||||
oatpp::Enum<Enum2>::AsString e2;
|
||||
|
||||
OATPP_ASSERT(!e1);
|
||||
OATPP_ASSERT(e1 == nullptr);
|
||||
OATPP_ASSERT(e1 == e2);
|
||||
OATPP_ASSERT(e2 == e1);
|
||||
|
||||
oatpp::Enum<Enum2>::NotNull e3;
|
||||
|
||||
OATPP_ASSERT(e1 == e3);
|
||||
OATPP_ASSERT(e3 == e1);
|
||||
|
||||
oatpp::Enum<Enum2>::AsNumber::NotNull e4;
|
||||
|
||||
OATPP_ASSERT(e1 == e4);
|
||||
OATPP_ASSERT(e4 == e1);
|
||||
|
||||
OATPP_ASSERT(e1.valueType != e4.valueType); // Types are not equal because interpreters are different
|
||||
OATPP_ASSERT(e1.valueType->classId.id == e4.valueType->classId.id); // But classId is the same
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test value constructor and == operators...");
|
||||
oatpp::Enum<Enum2> e1(Enum2::NAME_1);
|
||||
oatpp::Enum<Enum2> e2(Enum2::NAME_1);
|
||||
oatpp::Enum<Enum2> e3;
|
||||
|
||||
OATPP_ASSERT(e1);
|
||||
OATPP_ASSERT(e1 != nullptr);
|
||||
OATPP_ASSERT(e1 == e2);
|
||||
OATPP_ASSERT(e1 != e3);
|
||||
OATPP_ASSERT(e3 != e1);
|
||||
|
||||
OATPP_ASSERT(e1 == Enum2::NAME_1);
|
||||
OATPP_ASSERT(e1 != Enum2::NAME_2);
|
||||
OATPP_ASSERT(e3 != Enum2::NAME_1);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test copy-assignment operator...");
|
||||
oatpp::Enum<Enum2>::AsString e1;
|
||||
oatpp::Enum<Enum2>::AsNumber e2(Enum2::NAME_1);
|
||||
Enum2 ve;
|
||||
|
||||
OATPP_ASSERT(e1.valueType == oatpp::Enum<Enum2>::AsString::Class::getType());
|
||||
OATPP_ASSERT(e2.valueType == oatpp::Enum<Enum2>::AsNumber::Class::getType());
|
||||
OATPP_ASSERT(e1.valueType != e2.valueType);
|
||||
|
||||
e1 = e2;
|
||||
|
||||
OATPP_ASSERT(e1.valueType == oatpp::Enum<Enum2>::AsString::Class::getType());
|
||||
OATPP_ASSERT(e2.valueType == oatpp::Enum<Enum2>::AsNumber::Class::getType());
|
||||
OATPP_ASSERT(e1.valueType != e2.valueType);
|
||||
|
||||
OATPP_ASSERT(e1 == e2);
|
||||
OATPP_ASSERT(e2 == e1);
|
||||
OATPP_ASSERT(e1.get() == e2.get());
|
||||
|
||||
e1 = Enum2::NAME_2;
|
||||
|
||||
OATPP_ASSERT(e1 != e2);
|
||||
OATPP_ASSERT(e2 != e1);
|
||||
OATPP_ASSERT(e1.get() != e2.get());
|
||||
|
||||
OATPP_ASSERT(e1 == Enum2::NAME_2);
|
||||
OATPP_ASSERT(e2 == Enum2::NAME_1);
|
||||
|
||||
ve = e1;
|
||||
|
||||
OATPP_ASSERT(ve == Enum2::NAME_2);
|
||||
|
||||
ve = e2;
|
||||
|
||||
OATPP_ASSERT(ve == Enum2::NAME_1);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test move-assignment operator...");
|
||||
oatpp::Enum<Enum2>::AsString e1;
|
||||
oatpp::Enum<Enum2>::AsNumber e2(Enum2::NAME_1);
|
||||
|
||||
e1 = std::move(e2);
|
||||
|
||||
OATPP_ASSERT(e1);
|
||||
OATPP_ASSERT(!e2);
|
||||
|
||||
OATPP_ASSERT(e1 == Enum2::NAME_1);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/EnumTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/EnumTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_EnumTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_EnumTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class EnumTest : public UnitTest{
|
||||
public:
|
||||
|
||||
EnumTest():UnitTest("TEST[core::data::mapping::type::EnumTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_EnumTest_hpp */
|
160
test/oatpp/core/data/mapping/type/ListTest.cpp
Normal file
160
test/oatpp/core/data/mapping/type/ListTest.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ListTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
void ListTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor...");
|
||||
oatpp::List<oatpp::String> list;
|
||||
|
||||
OATPP_ASSERT(!list);
|
||||
OATPP_ASSERT(list == nullptr);
|
||||
|
||||
OATPP_ASSERT(list.get() == nullptr);
|
||||
OATPP_ASSERT(list.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
|
||||
OATPP_ASSERT(list.valueType->params.size() == 1);
|
||||
OATPP_ASSERT(list.valueType->params.front() == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test empty ilist constructor...");
|
||||
oatpp::List<oatpp::String> list({});
|
||||
|
||||
OATPP_ASSERT(list);
|
||||
OATPP_ASSERT(list != nullptr);
|
||||
OATPP_ASSERT(list->size() == 0);
|
||||
|
||||
OATPP_ASSERT(list.get() != nullptr);
|
||||
OATPP_ASSERT(list.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
|
||||
OATPP_ASSERT(list.valueType->params.size() == 1);
|
||||
OATPP_ASSERT(list.valueType->params.front() == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test createShared()...");
|
||||
oatpp::List<oatpp::String> list = oatpp::List<oatpp::String>::createShared();
|
||||
|
||||
OATPP_ASSERT(list);
|
||||
OATPP_ASSERT(list != nullptr);
|
||||
OATPP_ASSERT(list->size() == 0);
|
||||
|
||||
OATPP_ASSERT(list.get() != nullptr);
|
||||
OATPP_ASSERT(list.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-assignment operator...");
|
||||
oatpp::List<oatpp::String> list1({});
|
||||
oatpp::List<oatpp::String> list2;
|
||||
|
||||
list2 = list1;
|
||||
|
||||
OATPP_ASSERT(list1);
|
||||
OATPP_ASSERT(list2);
|
||||
|
||||
OATPP_ASSERT(list1->size() == 0);
|
||||
OATPP_ASSERT(list2->size() == 0);
|
||||
|
||||
OATPP_ASSERT(list1.get() == list2.get());
|
||||
|
||||
list2->push_back("a");
|
||||
|
||||
OATPP_ASSERT(list1->size() == 1);
|
||||
OATPP_ASSERT(list2->size() == 1);
|
||||
|
||||
list2 = {"b", "c"};
|
||||
|
||||
OATPP_ASSERT(list1->size() == 1);
|
||||
OATPP_ASSERT(list2->size() == 2);
|
||||
|
||||
OATPP_ASSERT(list2[0] == "b");
|
||||
OATPP_ASSERT(list2[1] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assignment operator...");
|
||||
oatpp::List<oatpp::String> list1({});
|
||||
oatpp::List<oatpp::String> list2;
|
||||
|
||||
list2 = std::move(list1);
|
||||
|
||||
OATPP_ASSERT(!list1);
|
||||
OATPP_ASSERT(list2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test get element by index...");
|
||||
oatpp::List<oatpp::String> list = {"a", "b", "c"};
|
||||
|
||||
OATPP_ASSERT(list);
|
||||
OATPP_ASSERT(list != nullptr);
|
||||
OATPP_ASSERT(list->size() == 3);
|
||||
|
||||
OATPP_ASSERT(list[0] == "a");
|
||||
OATPP_ASSERT(list[1] == "b");
|
||||
OATPP_ASSERT(list[2] == "c");
|
||||
|
||||
list[1] = "Hello!";
|
||||
|
||||
OATPP_ASSERT(list->size() == 3);
|
||||
|
||||
OATPP_ASSERT(list[0] == "a");
|
||||
OATPP_ASSERT(list[1] == "Hello!");
|
||||
OATPP_ASSERT(list[2] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test polymorphicDispatcher...");
|
||||
oatpp::List<oatpp::String> list = {"a", "b", "c"};
|
||||
|
||||
auto polymorphicDispatcher = static_cast<const typename oatpp::List<oatpp::String>::Class::AbstractPolymorphicDispatcher*>(
|
||||
list.valueType->polymorphicDispatcher
|
||||
);
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(list, oatpp::String("d"));
|
||||
|
||||
OATPP_ASSERT(list->size() == 4);
|
||||
|
||||
OATPP_ASSERT(list[0] == "a");
|
||||
OATPP_ASSERT(list[1] == "b");
|
||||
OATPP_ASSERT(list[2] == "c");
|
||||
OATPP_ASSERT(list[3] == "d");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/ListTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/ListTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_ListTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_ListTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class ListTest : public UnitTest{
|
||||
public:
|
||||
|
||||
ListTest():UnitTest("TEST[core::data::mapping::type::ListTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_ListTest_hpp */
|
301
test/oatpp/core/data/mapping/type/ObjectTest.cpp
Normal file
301
test/oatpp/core/data/mapping/type/ObjectTest.cpp
Normal file
@ -0,0 +1,301 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ObjectTest.hpp"
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include "oatpp-test/Checker.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class Dto0 : public oatpp::Object {
|
||||
DTO_INIT(Dto0, Object)
|
||||
};
|
||||
|
||||
class DtoA : public oatpp::Object {
|
||||
|
||||
DTO_INIT(DtoA, Object)
|
||||
|
||||
DTO_FIELD_INFO(id) {
|
||||
info->description = "identifier";
|
||||
}
|
||||
DTO_FIELD(String, id) = "Some default id";
|
||||
|
||||
DTO_HC_EQ(id)
|
||||
|
||||
public:
|
||||
|
||||
DtoA(const String& pId)
|
||||
: id(pId)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
class DtoB : public DtoA {
|
||||
|
||||
DTO_INIT(DtoB, DtoA)
|
||||
|
||||
DTO_FIELD_INFO(a) {
|
||||
info->description = "some field with a qualified name";
|
||||
}
|
||||
DTO_FIELD(String, a, "field-a") = "default-value";
|
||||
|
||||
};
|
||||
|
||||
class DtoC : public DtoA {
|
||||
|
||||
DTO_INIT(DtoC, DtoA)
|
||||
|
||||
DTO_FIELD(String, a);
|
||||
DTO_FIELD(String, b);
|
||||
DTO_FIELD(String, c);
|
||||
|
||||
DTO_HC_EQ(a, b, c);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
void runDtoInitializations() {
|
||||
for(v_int32 i = 0; i < 1000; i ++) {
|
||||
auto dto = DtoB::createShared();
|
||||
}
|
||||
}
|
||||
|
||||
void runDtoInitializetionsInThreads() {
|
||||
|
||||
std::list<std::thread> threads;
|
||||
for(v_int32 i = 0; i < 500; i++) {
|
||||
threads.push_back(std::thread(runDtoInitializations));
|
||||
}
|
||||
|
||||
for(auto& t : threads) {
|
||||
t.join();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ObjectTest::onRun() {
|
||||
|
||||
{
|
||||
oatpp::test::PerformanceChecker timer("DTO - Initializations.");
|
||||
runDtoInitializetionsInThreads();
|
||||
}
|
||||
|
||||
{
|
||||
auto dto = DtoA::createShared("id1");
|
||||
OATPP_ASSERT(dto->id == "id1");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Meta 1...");
|
||||
|
||||
auto type = DtoA::ObjectWrapper::Class::getType();
|
||||
const auto& propsMap = type->propertiesGetter()->getMap();
|
||||
|
||||
OATPP_ASSERT(propsMap.size() == 1);
|
||||
|
||||
auto it = propsMap.find("id");
|
||||
OATPP_ASSERT(it != propsMap.end());
|
||||
OATPP_ASSERT(it->second->info.description == "identifier");
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Meta 2...");
|
||||
|
||||
auto type = DtoB::ObjectWrapper::Class::getType();
|
||||
const auto& propsMap = type->propertiesGetter()->getMap();
|
||||
|
||||
OATPP_ASSERT(propsMap.size() == 2);
|
||||
|
||||
{
|
||||
auto it = propsMap.find("id");
|
||||
OATPP_ASSERT("id" && it != propsMap.end());
|
||||
OATPP_ASSERT(it->second->info.description == "identifier");
|
||||
}
|
||||
|
||||
{
|
||||
auto it = propsMap.find("field-a");
|
||||
OATPP_ASSERT("field-a" && it != propsMap.end());
|
||||
OATPP_ASSERT(it->second->info.description == "some field with a qualified name");
|
||||
}
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 1...");
|
||||
DtoA::ObjectWrapper a;
|
||||
OATPP_ASSERT(!a);
|
||||
OATPP_ASSERT(a == nullptr);
|
||||
OATPP_ASSERT(a.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 2...");
|
||||
DtoA::ObjectWrapper a;
|
||||
DtoA::ObjectWrapper b;
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 3...");
|
||||
auto a = DtoA::createShared();
|
||||
DtoA::ObjectWrapper b;
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(b != a);
|
||||
auto ohc = a->hashCode();
|
||||
auto whc = std::hash<DtoA::ObjectWrapper>{}(a);
|
||||
OATPP_ASSERT(ohc == whc);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 4...");
|
||||
auto a = Dto0::createShared();
|
||||
auto b = Dto0::createShared();
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 5...");
|
||||
auto a = DtoA::createShared();
|
||||
auto b = DtoA::createShared();
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
|
||||
a->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
b->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 6...");
|
||||
auto a = DtoB::createShared();
|
||||
auto b = DtoB::createShared();
|
||||
|
||||
OATPP_ASSERT(a->a == "default-value");
|
||||
OATPP_ASSERT(b->a == "default-value");
|
||||
|
||||
a->a = "value1"; // value that is ignored in HC & EQ
|
||||
a->a = "value2"; // value that is ignored in HC & EQ
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
|
||||
a->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
b->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 7...");
|
||||
auto a = DtoC::createShared();
|
||||
auto b = DtoC::createShared();
|
||||
|
||||
a->id = "1";
|
||||
b->id = "2";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
a->id = "2";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
|
||||
a->c = "a";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
b->c = "a";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 8...");
|
||||
auto a = DtoB::createShared();
|
||||
auto b = DtoB::createShared();
|
||||
auto c = DtoB::createShared();
|
||||
auto d = DtoB::createShared();
|
||||
auto e = DtoB::createShared();
|
||||
|
||||
a->a = "1";
|
||||
b->a = "2";
|
||||
c->a = "3";
|
||||
d->a = "4";
|
||||
e->a = "5";
|
||||
|
||||
a->id = "1";
|
||||
e->id = "1";
|
||||
|
||||
oatpp::UnorderedSet<DtoB> set = {a, b, c, d, e};
|
||||
|
||||
OATPP_ASSERT(set->size() == 2);
|
||||
OATPP_ASSERT(set[a] == true);
|
||||
OATPP_ASSERT(set[b] == true);
|
||||
OATPP_ASSERT(set[c] == true);
|
||||
OATPP_ASSERT(set[d] == true);
|
||||
OATPP_ASSERT(set[e] == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/ObjectTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/ObjectTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_ObjectTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_ObjectTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class ObjectTest : public UnitTest{
|
||||
public:
|
||||
|
||||
ObjectTest():UnitTest("TEST[core::data::mapping::type::ObjectTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_ObjectTest_hpp */
|
169
test/oatpp/core/data/mapping/type/ObjectWrapperTest.cpp
Normal file
169
test/oatpp/core/data/mapping/type/ObjectWrapperTest.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ObjectWrapperTest.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace {
|
||||
|
||||
template<class T, class Clazz = oatpp::data::mapping::type::__class::Void>
|
||||
using ObjectWrapper = oatpp::data::mapping::type::ObjectWrapper<T, Clazz>;
|
||||
|
||||
}
|
||||
|
||||
void ObjectWrapperTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check default valueType is assigned (default tparam Clazz)...");
|
||||
ObjectWrapper<base::StrBuffer> pw;
|
||||
OATPP_ASSERT(!pw);
|
||||
OATPP_ASSERT(pw == nullptr);
|
||||
OATPP_ASSERT(pw.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check default valueType is assigned (specified tparam Clazz)...");
|
||||
ObjectWrapper<base::StrBuffer, oatpp::data::mapping::type::__class::String> pw;
|
||||
OATPP_ASSERT(!pw);
|
||||
OATPP_ASSERT(pw == nullptr);
|
||||
OATPP_ASSERT(pw.valueType == oatpp::data::mapping::type::__class::String::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check valueType is assigned from constructor...");
|
||||
ObjectWrapper<base::StrBuffer> pw(oatpp::data::mapping::type::__class::String::getType());
|
||||
OATPP_ASSERT(!pw);
|
||||
OATPP_ASSERT(pw == nullptr);
|
||||
OATPP_ASSERT(pw.valueType == oatpp::data::mapping::type::__class::String::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check valueType is assigned from copy constructor...");
|
||||
ObjectWrapper<base::StrBuffer> pw1(oatpp::data::mapping::type::__class::String::getType());
|
||||
ObjectWrapper<base::StrBuffer> pw2(pw1);
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::String::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check valueType is assigned from move constructor...");
|
||||
ObjectWrapper<base::StrBuffer> pw1(oatpp::data::mapping::type::__class::String::getType());
|
||||
ObjectWrapper<base::StrBuffer> pw2(std::move(pw1));
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::String::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check valueType is NOT assigned from copy-assign operator...");
|
||||
ObjectWrapper<base::StrBuffer> pw1(oatpp::data::mapping::type::__class::String::getType());
|
||||
ObjectWrapper<base::StrBuffer> pw2;
|
||||
pw2 = pw1;
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check valueType is NOT assigned from move-assign operator...");
|
||||
ObjectWrapper<base::StrBuffer> pw1(oatpp::data::mapping::type::__class::String::getType());
|
||||
ObjectWrapper<base::StrBuffer> pw2;
|
||||
pw2 = std::move(pw1);
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check copy-assign operator. Check == operator...");
|
||||
ObjectWrapper<base::StrBuffer> pw1;
|
||||
OATPP_ASSERT(!pw1);
|
||||
OATPP_ASSERT(pw1 == nullptr);
|
||||
OATPP_ASSERT(pw1.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
|
||||
ObjectWrapper<base::StrBuffer> pw2 = base::StrBuffer::createShared("Hello!");
|
||||
OATPP_ASSERT(pw2);
|
||||
OATPP_ASSERT(pw2 != nullptr);
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
|
||||
pw1 = pw2;
|
||||
|
||||
OATPP_ASSERT(pw1);
|
||||
OATPP_ASSERT(pw1 != nullptr);
|
||||
|
||||
OATPP_ASSERT(pw2);
|
||||
OATPP_ASSERT(pw2 != nullptr);
|
||||
|
||||
OATPP_ASSERT(pw1 == pw2);
|
||||
OATPP_ASSERT(pw1.get() == pw2.get());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check != operator...");
|
||||
ObjectWrapper<base::StrBuffer, oatpp::data::mapping::type::__class::String> pw1(base::StrBuffer::createShared("Hello!"));
|
||||
OATPP_ASSERT(pw1);
|
||||
OATPP_ASSERT(pw1 != nullptr);
|
||||
OATPP_ASSERT(pw1.valueType == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
ObjectWrapper<base::StrBuffer, oatpp::data::mapping::type::__class::String> pw2(base::StrBuffer::createShared("Hello!"));
|
||||
OATPP_ASSERT(pw2);
|
||||
OATPP_ASSERT(pw2 != nullptr);
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::String::getType());
|
||||
|
||||
OATPP_ASSERT(pw1 != pw2);
|
||||
OATPP_ASSERT(pw1.get() != pw2.get());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Check move-assign operator. Check != operator...");
|
||||
ObjectWrapper<base::StrBuffer> pw1;
|
||||
OATPP_ASSERT(!pw1);
|
||||
OATPP_ASSERT(pw1 == nullptr);
|
||||
OATPP_ASSERT(pw1.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
|
||||
ObjectWrapper<base::StrBuffer> pw2 = base::StrBuffer::createShared("Hello!");
|
||||
OATPP_ASSERT(pw2);
|
||||
OATPP_ASSERT(pw2 != nullptr);
|
||||
OATPP_ASSERT(pw2.valueType == oatpp::data::mapping::type::__class::Void::getType());
|
||||
|
||||
pw1 = std::move(pw2);
|
||||
|
||||
OATPP_ASSERT(pw1);
|
||||
OATPP_ASSERT(pw1 != nullptr);
|
||||
|
||||
OATPP_ASSERT(!pw2);
|
||||
OATPP_ASSERT(pw2 == nullptr);
|
||||
|
||||
OATPP_ASSERT(pw1 != pw2);
|
||||
OATPP_ASSERT(pw1.get() != pw2.get());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/ObjectWrapperTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/ObjectWrapperTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_ObjectWrapperTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_ObjectWrapperTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class ObjectWrapperTest : public UnitTest{
|
||||
public:
|
||||
|
||||
ObjectWrapperTest():UnitTest("TEST[core::data::mapping::type::ObjectWrapperTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_ObjectWrapperTest_hpp */
|
164
test/oatpp/core/data/mapping/type/PairListTest.cpp
Normal file
164
test/oatpp/core/data/mapping/type/PairListTest.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "PairListTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
void PairListTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor...");
|
||||
oatpp::Fields<String> map;
|
||||
|
||||
OATPP_ASSERT(!map);
|
||||
OATPP_ASSERT(map == nullptr);
|
||||
|
||||
OATPP_ASSERT(map.get() == nullptr);
|
||||
OATPP_ASSERT(map.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id);
|
||||
OATPP_ASSERT(map.valueType->params.size() == 2);
|
||||
auto it = map.valueType->params.begin();
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test empty ilist constructor...");
|
||||
oatpp::Fields<String> map({});
|
||||
|
||||
OATPP_ASSERT(map);
|
||||
OATPP_ASSERT(map != nullptr);
|
||||
OATPP_ASSERT(map->size() == 0);
|
||||
|
||||
OATPP_ASSERT(map.get() != nullptr);
|
||||
OATPP_ASSERT(map.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id);
|
||||
OATPP_ASSERT(map.valueType->params.size() == 2);
|
||||
auto it = map.valueType->params.begin();
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test createShared()...");
|
||||
oatpp::Fields<String> map = oatpp::Fields<String>::createShared();
|
||||
|
||||
OATPP_ASSERT(map);
|
||||
OATPP_ASSERT(map != nullptr);
|
||||
OATPP_ASSERT(map->size() == 0);
|
||||
|
||||
OATPP_ASSERT(map.get() != nullptr);
|
||||
OATPP_ASSERT(map.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-assignment operator...");
|
||||
oatpp::Fields<String> map1({});
|
||||
oatpp::Fields<String> map2;
|
||||
|
||||
map2 = map1;
|
||||
|
||||
OATPP_ASSERT(map1);
|
||||
OATPP_ASSERT(map2);
|
||||
|
||||
OATPP_ASSERT(map1->size() == 0);
|
||||
OATPP_ASSERT(map2->size() == 0);
|
||||
|
||||
OATPP_ASSERT(map1.get() == map2.get());
|
||||
|
||||
map2->push_back({"key", "a"});
|
||||
|
||||
OATPP_ASSERT(map1->size() == 1);
|
||||
OATPP_ASSERT(map2->size() == 1);
|
||||
|
||||
map2 = {{"key1", "b"}, {"key2", "c"}};
|
||||
|
||||
OATPP_ASSERT(map1->size() == 1);
|
||||
OATPP_ASSERT(map2->size() == 2);
|
||||
|
||||
OATPP_ASSERT(map2["key1"] == "b");
|
||||
OATPP_ASSERT(map2["key2"] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assignment operator...");
|
||||
oatpp::Fields<String> map1({});
|
||||
oatpp::Fields<String> map2;
|
||||
|
||||
map2 = std::move(map1);
|
||||
|
||||
OATPP_ASSERT(!map1);
|
||||
OATPP_ASSERT(map2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test get element by index...");
|
||||
oatpp::Fields<String> map = {{"key1", "a"}, {"key2", "b"}, {"key3", "c"}};
|
||||
|
||||
OATPP_ASSERT(map);
|
||||
OATPP_ASSERT(map != nullptr);
|
||||
OATPP_ASSERT(map->size() == 3);
|
||||
|
||||
OATPP_ASSERT(map["key1"] == "a");
|
||||
OATPP_ASSERT(map["key2"] == "b");
|
||||
OATPP_ASSERT(map["key3"] == "c");
|
||||
|
||||
map["key2"] = "Hello!";
|
||||
|
||||
OATPP_ASSERT(map->size() == 3);
|
||||
|
||||
OATPP_ASSERT(map["key1"] == "a");
|
||||
OATPP_ASSERT(map["key2"] == "Hello!");
|
||||
OATPP_ASSERT(map["key3"] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test polymorphicDispatcher...");
|
||||
oatpp::Fields<String> map = {{"key1", "a"}, {"key2", "b"}, {"key3", "c"}};
|
||||
|
||||
auto polymorphicDispatcher = static_cast<const typename oatpp::Fields<String>::Class::AbstractPolymorphicDispatcher*>(
|
||||
map.valueType->polymorphicDispatcher
|
||||
);
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(map, oatpp::String("key1"), oatpp::String("d"));
|
||||
|
||||
OATPP_ASSERT(map->size() == 4);
|
||||
|
||||
OATPP_ASSERT(map[0].first == "key1" && map[0].second == "a");
|
||||
OATPP_ASSERT(map[1].first == "key2" && map[1].second == "b");
|
||||
OATPP_ASSERT(map[2].first == "key3" && map[2].second == "c");
|
||||
OATPP_ASSERT(map[3].first == "key1" && map[3].second == "d");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/PairListTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/PairListTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_PairListTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_PairListTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class PairListTest : public UnitTest{
|
||||
public:
|
||||
|
||||
PairListTest():UnitTest("TEST[core::data::mapping::type::PairListTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_PairListTest_hpp */
|
249
test/oatpp/core/data/mapping/type/PrimitiveTest.cpp
Normal file
249
test/oatpp/core/data/mapping/type/PrimitiveTest.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "PrimitiveTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace {
|
||||
|
||||
template<class T>
|
||||
void checkHash(const T& val) {
|
||||
auto h = std::hash<T>{}(val);
|
||||
OATPP_LOGI("HASH", "type='%s', hash=%llu", val.valueType->classId.name, h);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PrimitiveTest::onRun() {
|
||||
|
||||
{
|
||||
checkHash(oatpp::Boolean(true));
|
||||
checkHash(oatpp::Int8(0xFF));
|
||||
checkHash(oatpp::UInt8(0xFF));
|
||||
checkHash(oatpp::Int16(0xFFFF));
|
||||
checkHash(oatpp::UInt16(0xFFFF));
|
||||
checkHash(oatpp::Int32(0xFFFFFFFF));
|
||||
checkHash(oatpp::UInt32(0xFFFFFFFF));
|
||||
checkHash(oatpp::Int64(0xFFFFFFFFFFFFFFFF));
|
||||
checkHash(oatpp::UInt64(0xFFFFFFFFFFFFFFFF));
|
||||
checkHash(oatpp::Float32(0.2));
|
||||
checkHash(oatpp::Float64(0.2));
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor");
|
||||
oatpp::Int32 i;
|
||||
OATPP_ASSERT(!i);
|
||||
OATPP_ASSERT(i == nullptr);
|
||||
OATPP_ASSERT(i.valueType == oatpp::Int32::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test value constructor");
|
||||
oatpp::Int32 i(0);
|
||||
OATPP_ASSERT(i);
|
||||
OATPP_ASSERT(i != nullptr);
|
||||
OATPP_ASSERT(i == 0);
|
||||
OATPP_ASSERT(i.valueType == oatpp::Int32::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test implicit value constructor");
|
||||
oatpp::Int32 i = 0;
|
||||
OATPP_ASSERT(i);
|
||||
OATPP_ASSERT(i != nullptr);
|
||||
OATPP_ASSERT(i == 0);
|
||||
OATPP_ASSERT(i.valueType == oatpp::Int32::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test '==' and '!=' operators");
|
||||
oatpp::Int32 i1 = 0;
|
||||
oatpp::Int32 i2;
|
||||
|
||||
OATPP_ASSERT(i1);
|
||||
OATPP_ASSERT(i1 != nullptr);
|
||||
OATPP_ASSERT(i1 == 0);
|
||||
OATPP_ASSERT(i1 != 1);
|
||||
|
||||
OATPP_ASSERT(!i2);
|
||||
OATPP_ASSERT(i2 == nullptr)
|
||||
|
||||
OATPP_ASSERT(i1 != i2);
|
||||
OATPP_ASSERT(i2 != i1);
|
||||
|
||||
i2 = 0;
|
||||
|
||||
OATPP_ASSERT(i1 == i2);
|
||||
OATPP_ASSERT(i2 == i1);
|
||||
|
||||
i1 = nullptr;
|
||||
i2 = nullptr;
|
||||
|
||||
OATPP_ASSERT(i1 == i2);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-assign operator");
|
||||
oatpp::Int32 i1 = 0;
|
||||
oatpp::Int32 i2;
|
||||
|
||||
OATPP_ASSERT(i1 != i2);
|
||||
|
||||
i2 = i1;
|
||||
|
||||
OATPP_ASSERT(i1 == i2);
|
||||
OATPP_ASSERT(i1.get() == i2.get());
|
||||
|
||||
i2 = 1;
|
||||
|
||||
OATPP_ASSERT(i1 != i2);
|
||||
OATPP_ASSERT(i1.get() != i2.get());
|
||||
|
||||
OATPP_ASSERT(i1 == 0);
|
||||
OATPP_ASSERT(i2 == 1);
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assign operator");
|
||||
oatpp::Int32 i1 = 0;
|
||||
oatpp::Int32 i2;
|
||||
|
||||
OATPP_ASSERT(i1 != i2);
|
||||
|
||||
i2 = std::move(i1);
|
||||
|
||||
OATPP_ASSERT(i1 == nullptr);
|
||||
OATPP_ASSERT(i2 != nullptr);
|
||||
|
||||
OATPP_ASSERT(i2 == 0);
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assign operator");
|
||||
oatpp::Int32 i = 0;
|
||||
v_int32 v = i;
|
||||
OATPP_ASSERT(v == i);
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Boolean [nullptr]");
|
||||
oatpp::Boolean b;
|
||||
|
||||
OATPP_ASSERT(!b);
|
||||
OATPP_ASSERT(b == nullptr);
|
||||
OATPP_ASSERT(b != false);
|
||||
OATPP_ASSERT(b != true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Boolean nullptr constructor");
|
||||
oatpp::Boolean b = nullptr;
|
||||
|
||||
OATPP_ASSERT(!b);
|
||||
OATPP_ASSERT(b == nullptr);
|
||||
OATPP_ASSERT(b != false);
|
||||
OATPP_ASSERT(b != true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Boolean [false]");
|
||||
oatpp::Boolean b = false;
|
||||
|
||||
OATPP_ASSERT(!b); // <--- still !b
|
||||
OATPP_ASSERT(b != nullptr);
|
||||
OATPP_ASSERT(b == false);
|
||||
OATPP_ASSERT(b != true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Boolean [true]");
|
||||
oatpp::Boolean b = true;
|
||||
|
||||
OATPP_ASSERT(b);
|
||||
OATPP_ASSERT(b != nullptr);
|
||||
OATPP_ASSERT(b != false);
|
||||
OATPP_ASSERT(b == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Boolean copy-assign operator");
|
||||
oatpp::Boolean b1 = true;
|
||||
oatpp::Boolean b2;
|
||||
|
||||
b2 = b1;
|
||||
|
||||
OATPP_ASSERT(b2);
|
||||
OATPP_ASSERT(b1);
|
||||
OATPP_ASSERT(b1 == b2);
|
||||
OATPP_ASSERT(b1.get() == b2.get());
|
||||
|
||||
b2 = false;
|
||||
|
||||
OATPP_ASSERT(b1.get() != b2.get());
|
||||
OATPP_ASSERT(b1 != b2);
|
||||
OATPP_ASSERT(b2 != b1);
|
||||
|
||||
b1 = false;
|
||||
b2 = nullptr;
|
||||
|
||||
OATPP_ASSERT(b1 != b2);
|
||||
OATPP_ASSERT(b2 != b1);
|
||||
|
||||
b1 = nullptr;
|
||||
b2 = nullptr;
|
||||
|
||||
OATPP_ASSERT(b1 == b2);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test Boolean move-assign operator");
|
||||
oatpp::Boolean b1 = true;
|
||||
oatpp::Boolean b2;
|
||||
|
||||
b2 = std::move(b1);
|
||||
|
||||
OATPP_ASSERT(b2 != nullptr);
|
||||
OATPP_ASSERT(b1 == nullptr);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/PrimitiveTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/PrimitiveTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_PrimitiveTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_PrimitiveTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class PrimitiveTest : public UnitTest{
|
||||
public:
|
||||
|
||||
PrimitiveTest():UnitTest("TEST[core::data::mapping::type::PrimitiveTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_PrimitiveTest_hpp */
|
139
test/oatpp/core/data/mapping/type/StringTest.cpp
Normal file
139
test/oatpp/core/data/mapping/type/StringTest.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "StringTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
void StringTest::onRun() {
|
||||
|
||||
{
|
||||
oatpp::String s = "hello"; // check hash function exists
|
||||
std::hash<oatpp::String>{}(s);
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor");
|
||||
oatpp::String s;
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s == (const char*) nullptr);
|
||||
OATPP_ASSERT(s.valueType == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test const char* constructor");
|
||||
oatpp::String s("");
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s != (const char*) nullptr)
|
||||
OATPP_ASSERT(s->getSize() == 0);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test const char* implicit constructor");
|
||||
oatpp::String s = "";
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s != (const char*) nullptr)
|
||||
OATPP_ASSERT(s->getSize() == 0);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test '==', '!=' operators");
|
||||
oatpp::String s1 = "a";
|
||||
oatpp::String s2;
|
||||
|
||||
OATPP_ASSERT(s1 != s2);
|
||||
OATPP_ASSERT(s2 != s1);
|
||||
|
||||
OATPP_ASSERT(s1 == "a");
|
||||
OATPP_ASSERT(s1 != "aa");
|
||||
OATPP_ASSERT(s1 != "");
|
||||
|
||||
s2 = "aa";
|
||||
|
||||
OATPP_ASSERT(s1 != s2);
|
||||
OATPP_ASSERT(s2 != s1);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-asssign operator");
|
||||
oatpp::String s1 = "s1";
|
||||
oatpp::String s2;
|
||||
|
||||
s2 = s1;
|
||||
|
||||
OATPP_ASSERT(s1 == s2);
|
||||
OATPP_ASSERT(s1.get() == s2.get());
|
||||
|
||||
s1 = "s2";
|
||||
|
||||
OATPP_ASSERT(s1 != s2);
|
||||
OATPP_ASSERT(s2 != s1);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test const char* assign operator");
|
||||
oatpp::String s1 = "s1";
|
||||
oatpp::String s2(s1);
|
||||
|
||||
OATPP_ASSERT(s1 == s2);
|
||||
OATPP_ASSERT(s1.get() == s2.get());
|
||||
|
||||
s1 = "s2";
|
||||
|
||||
OATPP_ASSERT(s1 != s2);
|
||||
OATPP_ASSERT(s2 != s1);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move assign operator");
|
||||
oatpp::String s1 = "s1";
|
||||
oatpp::String s2;
|
||||
|
||||
s2 = std::move(s1);
|
||||
|
||||
OATPP_ASSERT(s1 == nullptr);
|
||||
OATPP_ASSERT(s2 != nullptr);
|
||||
OATPP_ASSERT(s2 == "s1");
|
||||
|
||||
OATPP_ASSERT(s1 != s2);
|
||||
OATPP_ASSERT(s1.get() != s2.get());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/StringTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/StringTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_StringTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_StringTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class StringTest : public UnitTest{
|
||||
public:
|
||||
|
||||
StringTest():UnitTest("TEST[core::data::mapping::type::StringTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_StringTest_hpp */
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
@ -33,11 +34,9 @@ namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
typedef oatpp::data::mapping::type::Object DTO;
|
||||
|
||||
class TestDto : public DTO {
|
||||
class TestDto : public oatpp::Object {
|
||||
|
||||
DTO_INIT(TestDto, DTO);
|
||||
DTO_INIT(TestDto, Object);
|
||||
|
||||
DTO_FIELD(String, field_string);
|
||||
DTO_FIELD(Int8, field_int8);
|
||||
@ -48,16 +47,16 @@ namespace {
|
||||
DTO_FIELD(Float64, field_float64);
|
||||
DTO_FIELD(Boolean, field_boolean);
|
||||
|
||||
DTO_FIELD(List<String>::ObjectWrapper, field_list_string);
|
||||
DTO_FIELD(List<Int32>::ObjectWrapper, field_list_int32);
|
||||
DTO_FIELD(List<Int64>::ObjectWrapper, field_list_int64);
|
||||
DTO_FIELD(List<Float32>::ObjectWrapper, field_list_float32);
|
||||
DTO_FIELD(List<Float64>::ObjectWrapper, field_list_float64);
|
||||
DTO_FIELD(List<Boolean>::ObjectWrapper, field_list_boolean);
|
||||
DTO_FIELD(List<String>, field_list_string);
|
||||
DTO_FIELD(List<Int32>, field_list_int32);
|
||||
DTO_FIELD(List<Int64>, field_list_int64);
|
||||
DTO_FIELD(List<Float32>, field_list_float32);
|
||||
DTO_FIELD(List<Float64>, field_list_float64);
|
||||
DTO_FIELD(List<Boolean>, field_list_boolean);
|
||||
|
||||
DTO_FIELD(Fields<String>::ObjectWrapper, field_map_string_string);
|
||||
DTO_FIELD(Fields<String>, field_map_string_string);
|
||||
|
||||
DTO_FIELD(TestDto::ObjectWrapper, obj1);
|
||||
DTO_FIELD(TestDto, obj1);
|
||||
|
||||
};
|
||||
|
||||
@ -112,7 +111,7 @@ void TypeTest::onRun() {
|
||||
OATPP_ASSERT(obj->field_list_boolean.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractList::CLASS_ID.id);
|
||||
|
||||
OATPP_LOGV(TAG, "type: '%s'", obj->field_map_string_string.valueType->classId.name);
|
||||
OATPP_ASSERT(obj->field_map_string_string.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractListMap::CLASS_ID.id);
|
||||
OATPP_ASSERT(obj->field_map_string_string.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractPairList::CLASS_ID.id);
|
||||
|
||||
OATPP_LOGV(TAG, "type: '%s'", obj->obj1.valueType->classId.name);
|
||||
OATPP_ASSERT(obj->obj1.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id);
|
||||
|
163
test/oatpp/core/data/mapping/type/UnorderedMapTest.cpp
Normal file
163
test/oatpp/core/data/mapping/type/UnorderedMapTest.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "UnorderedMapTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
void UnorderedMapTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor...");
|
||||
oatpp::UnorderedFields<String> map;
|
||||
|
||||
OATPP_ASSERT(!map);
|
||||
OATPP_ASSERT(map == nullptr);
|
||||
|
||||
OATPP_ASSERT(map.get() == nullptr);
|
||||
OATPP_ASSERT(map.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID.id);
|
||||
OATPP_ASSERT(map.valueType->params.size() == 2);
|
||||
auto it = map.valueType->params.begin();
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test empty ilist constructor...");
|
||||
oatpp::UnorderedFields<String> map({});
|
||||
|
||||
OATPP_ASSERT(map);
|
||||
OATPP_ASSERT(map != nullptr);
|
||||
OATPP_ASSERT(map->size() == 0);
|
||||
|
||||
OATPP_ASSERT(map.get() != nullptr);
|
||||
OATPP_ASSERT(map.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID.id);
|
||||
OATPP_ASSERT(map.valueType->params.size() == 2);
|
||||
auto it = map.valueType->params.begin();
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_ASSERT(*it++ == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test createShared()...");
|
||||
oatpp::UnorderedFields<String> map = oatpp::UnorderedFields<String>::createShared();
|
||||
|
||||
OATPP_ASSERT(map);
|
||||
OATPP_ASSERT(map != nullptr);
|
||||
OATPP_ASSERT(map->size() == 0);
|
||||
|
||||
OATPP_ASSERT(map.get() != nullptr);
|
||||
OATPP_ASSERT(map.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedMap::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-assignment operator...");
|
||||
oatpp::UnorderedFields<String> map1({});
|
||||
oatpp::UnorderedFields<String> map2;
|
||||
|
||||
map2 = map1;
|
||||
|
||||
OATPP_ASSERT(map1);
|
||||
OATPP_ASSERT(map2);
|
||||
|
||||
OATPP_ASSERT(map1->size() == 0);
|
||||
OATPP_ASSERT(map2->size() == 0);
|
||||
|
||||
OATPP_ASSERT(map1.get() == map2.get());
|
||||
|
||||
map2->insert({"key", "a"});
|
||||
|
||||
OATPP_ASSERT(map1->size() == 1);
|
||||
OATPP_ASSERT(map2->size() == 1);
|
||||
|
||||
map2 = {{"key1", "b"}, {"key2", "c"}};
|
||||
|
||||
OATPP_ASSERT(map1->size() == 1);
|
||||
OATPP_ASSERT(map2->size() == 2);
|
||||
|
||||
OATPP_ASSERT(map2["key1"] == "b");
|
||||
OATPP_ASSERT(map2["key2"] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assignment operator...");
|
||||
oatpp::UnorderedFields<String> map1({});
|
||||
oatpp::UnorderedFields<String> map2;
|
||||
|
||||
map2 = std::move(map1);
|
||||
|
||||
OATPP_ASSERT(!map1);
|
||||
OATPP_ASSERT(map2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test get element by index...");
|
||||
oatpp::UnorderedFields<String> map = {{"key1", "a"}, {"key2", "b"}, {"key3", "c"}};
|
||||
|
||||
OATPP_ASSERT(map);
|
||||
OATPP_ASSERT(map != nullptr);
|
||||
OATPP_ASSERT(map->size() == 3);
|
||||
|
||||
OATPP_ASSERT(map["key1"] == "a");
|
||||
OATPP_ASSERT(map["key2"] == "b");
|
||||
OATPP_ASSERT(map["key3"] == "c");
|
||||
|
||||
map["key2"] = "Hello!";
|
||||
|
||||
OATPP_ASSERT(map->size() == 3);
|
||||
|
||||
OATPP_ASSERT(map["key1"] == "a");
|
||||
OATPP_ASSERT(map["key2"] == "Hello!");
|
||||
OATPP_ASSERT(map["key3"] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test polymorphicDispatcher...");
|
||||
oatpp::UnorderedFields<String> map = {{"key1", "a"}, {"key2", "b"}, {"key3", "c"}};
|
||||
|
||||
auto polymorphicDispatcher = static_cast<const typename oatpp::UnorderedFields<String>::Class::AbstractPolymorphicDispatcher*>(
|
||||
map.valueType->polymorphicDispatcher
|
||||
);
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(map, oatpp::String("key1"), oatpp::String("d"));
|
||||
|
||||
OATPP_ASSERT(map->size() == 3);
|
||||
|
||||
OATPP_ASSERT(map["key1"] == "d");
|
||||
OATPP_ASSERT(map["key2"] == "b");
|
||||
OATPP_ASSERT(map["key3"] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/UnorderedMapTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/UnorderedMapTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_UnorderedMapTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_UnorderedMapTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class UnorderedMapTest : public UnitTest{
|
||||
public:
|
||||
|
||||
UnorderedMapTest():UnitTest("TEST[core::data::mapping::type::UnorderedMapTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_UnorderedMapTest_hpp */
|
144
test/oatpp/core/data/mapping/type/UnorderedSetTest.cpp
Normal file
144
test/oatpp/core/data/mapping/type/UnorderedSetTest.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "UnorderedSetTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
void UnorderedSetTest::onRun() {
|
||||
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor...");
|
||||
oatpp::UnorderedSet<oatpp::String> set;
|
||||
|
||||
OATPP_ASSERT(!set);
|
||||
OATPP_ASSERT(set == nullptr);
|
||||
|
||||
OATPP_ASSERT(set.get() == nullptr);
|
||||
OATPP_ASSERT(set.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id);
|
||||
OATPP_ASSERT(set.valueType->params.size() == 1);
|
||||
OATPP_ASSERT(set.valueType->params.front() == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test empty ilist constructor...");
|
||||
oatpp::UnorderedSet<oatpp::String> set({});
|
||||
|
||||
OATPP_ASSERT(set);
|
||||
OATPP_ASSERT(set != nullptr);
|
||||
OATPP_ASSERT(set->size() == 0);
|
||||
|
||||
OATPP_ASSERT(set.get() != nullptr);
|
||||
OATPP_ASSERT(set.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id);
|
||||
OATPP_ASSERT(set.valueType->params.size() == 1);
|
||||
OATPP_ASSERT(set.valueType->params.front() == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test createShared()...");
|
||||
oatpp::UnorderedSet<oatpp::String> set = oatpp::UnorderedSet<oatpp::String>::createShared();
|
||||
|
||||
OATPP_ASSERT(set);
|
||||
OATPP_ASSERT(set != nullptr);
|
||||
OATPP_ASSERT(set->size() == 0);
|
||||
|
||||
OATPP_ASSERT(set.get() != nullptr);
|
||||
OATPP_ASSERT(set.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractUnorderedSet::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-assignment operator...");
|
||||
oatpp::UnorderedSet<oatpp::String> set1({});
|
||||
oatpp::UnorderedSet<oatpp::String> set2;
|
||||
|
||||
set2 = set1;
|
||||
|
||||
OATPP_ASSERT(set1);
|
||||
OATPP_ASSERT(set2);
|
||||
|
||||
OATPP_ASSERT(set1->size() == 0);
|
||||
OATPP_ASSERT(set2->size() == 0);
|
||||
|
||||
OATPP_ASSERT(set1.get() == set2.get());
|
||||
|
||||
set2->insert("a");
|
||||
|
||||
OATPP_ASSERT(set1->size() == 1);
|
||||
OATPP_ASSERT(set2->size() == 1);
|
||||
|
||||
set2 = {"b", "c"};
|
||||
|
||||
OATPP_ASSERT(set1->size() == 1);
|
||||
OATPP_ASSERT(set2->size() == 2);
|
||||
|
||||
OATPP_ASSERT(set2["b"] == true);
|
||||
OATPP_ASSERT(set2["c"] == true);
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assignment operator...");
|
||||
oatpp::UnorderedSet<oatpp::String> set1({});
|
||||
oatpp::UnorderedSet<oatpp::String> set2;
|
||||
|
||||
set2 = std::move(set1);
|
||||
|
||||
OATPP_ASSERT(!set1);
|
||||
OATPP_ASSERT(set2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test polymorphicDispatcher...");
|
||||
oatpp::UnorderedSet<oatpp::String> set = {"a", "b", "c"};
|
||||
|
||||
auto polymorphicDispatcher = static_cast<const typename oatpp::UnorderedSet<oatpp::String>::Class::AbstractPolymorphicDispatcher*>(
|
||||
set.valueType->polymorphicDispatcher
|
||||
);
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(set, oatpp::String("a"));
|
||||
polymorphicDispatcher->addPolymorphicItem(set, oatpp::String("b"));
|
||||
polymorphicDispatcher->addPolymorphicItem(set, oatpp::String("c"));
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(set, oatpp::String("d"));
|
||||
|
||||
OATPP_ASSERT(set->size() == 4);
|
||||
|
||||
OATPP_ASSERT(set["a"]);
|
||||
OATPP_ASSERT(set["b"]);
|
||||
OATPP_ASSERT(set["c"]);
|
||||
OATPP_ASSERT(set["d"]);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/UnorderedSetTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/UnorderedSetTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_UnorderedSetTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_UnorderedSetTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class UnorderedSetTest : public UnitTest{
|
||||
public:
|
||||
|
||||
UnorderedSetTest():UnitTest("TEST[core::data::mapping::type::UnorderedSetTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_UnorderedSetTest_hpp */
|
160
test/oatpp/core/data/mapping/type/VectorTest.cpp
Normal file
160
test/oatpp/core/data/mapping/type/VectorTest.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "VectorTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
void VectorTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test default constructor...");
|
||||
oatpp::Vector<oatpp::String> vector;
|
||||
|
||||
OATPP_ASSERT(!vector);
|
||||
OATPP_ASSERT(vector == nullptr);
|
||||
|
||||
OATPP_ASSERT(vector.get() == nullptr);
|
||||
OATPP_ASSERT(vector.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractVector::CLASS_ID.id);
|
||||
OATPP_ASSERT(vector.valueType->params.size() == 1);
|
||||
OATPP_ASSERT(vector.valueType->params.front() == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test empty ilist constructor...");
|
||||
oatpp::Vector<oatpp::String> vector({});
|
||||
|
||||
OATPP_ASSERT(vector);
|
||||
OATPP_ASSERT(vector != nullptr);
|
||||
OATPP_ASSERT(vector->size() == 0);
|
||||
|
||||
OATPP_ASSERT(vector.get() != nullptr);
|
||||
OATPP_ASSERT(vector.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractVector::CLASS_ID.id);
|
||||
OATPP_ASSERT(vector.valueType->params.size() == 1);
|
||||
OATPP_ASSERT(vector.valueType->params.front() == oatpp::String::Class::getType());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test createShared()...");
|
||||
oatpp::Vector<oatpp::String> vector = oatpp::Vector<oatpp::String>::createShared();
|
||||
|
||||
OATPP_ASSERT(vector);
|
||||
OATPP_ASSERT(vector != nullptr);
|
||||
OATPP_ASSERT(vector->size() == 0);
|
||||
|
||||
OATPP_ASSERT(vector.get() != nullptr);
|
||||
OATPP_ASSERT(vector.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractVector::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test copy-assignment operator...");
|
||||
oatpp::Vector<oatpp::String> vector1({});
|
||||
oatpp::Vector<oatpp::String> vector2;
|
||||
|
||||
vector2 = vector1;
|
||||
|
||||
OATPP_ASSERT(vector1);
|
||||
OATPP_ASSERT(vector2);
|
||||
|
||||
OATPP_ASSERT(vector1->size() == 0);
|
||||
OATPP_ASSERT(vector2->size() == 0);
|
||||
|
||||
OATPP_ASSERT(vector1.get() == vector2.get());
|
||||
|
||||
vector2->push_back("a");
|
||||
|
||||
OATPP_ASSERT(vector1->size() == 1);
|
||||
OATPP_ASSERT(vector2->size() == 1);
|
||||
|
||||
vector2 = {"b", "c"};
|
||||
|
||||
OATPP_ASSERT(vector1->size() == 1);
|
||||
OATPP_ASSERT(vector2->size() == 2);
|
||||
|
||||
OATPP_ASSERT(vector2[0] == "b");
|
||||
OATPP_ASSERT(vector2[1] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test move-assignment operator...");
|
||||
oatpp::Vector<oatpp::String> vector1({});
|
||||
oatpp::Vector<oatpp::String> vector2;
|
||||
|
||||
vector2 = std::move(vector1);
|
||||
|
||||
OATPP_ASSERT(!vector1);
|
||||
OATPP_ASSERT(vector2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test get element by index...");
|
||||
oatpp::Vector<oatpp::String> vector = {"a", "b", "c"};
|
||||
|
||||
OATPP_ASSERT(vector);
|
||||
OATPP_ASSERT(vector != nullptr);
|
||||
OATPP_ASSERT(vector->size() == 3);
|
||||
|
||||
OATPP_ASSERT(vector[0] == "a");
|
||||
OATPP_ASSERT(vector[1] == "b");
|
||||
OATPP_ASSERT(vector[2] == "c");
|
||||
|
||||
vector[1] = "Hello!";
|
||||
|
||||
OATPP_ASSERT(vector->size() == 3);
|
||||
|
||||
OATPP_ASSERT(vector[0] == "a");
|
||||
OATPP_ASSERT(vector[1] == "Hello!");
|
||||
OATPP_ASSERT(vector[2] == "c");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "test polymorphicDispatcher...");
|
||||
oatpp::Vector<oatpp::String> vector = {"a", "b", "c"};
|
||||
|
||||
auto polymorphicDispatcher = static_cast<const typename oatpp::Vector<oatpp::String>::Class::AbstractPolymorphicDispatcher*>(
|
||||
vector.valueType->polymorphicDispatcher
|
||||
);
|
||||
|
||||
polymorphicDispatcher->addPolymorphicItem(vector, oatpp::String("d"));
|
||||
|
||||
OATPP_ASSERT(vector->size() == 4);
|
||||
|
||||
OATPP_ASSERT(vector[0] == "a");
|
||||
OATPP_ASSERT(vector[1] == "b");
|
||||
OATPP_ASSERT(vector[2] == "c");
|
||||
OATPP_ASSERT(vector[3] == "d");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/VectorTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/VectorTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_core_data_mapping_type_VectorTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_VectorTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class VectorTest : public UnitTest{
|
||||
public:
|
||||
|
||||
VectorTest():UnitTest("TEST[core::data::mapping::type::VectorTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_VectorTest_hpp */
|
@ -25,6 +25,7 @@
|
||||
#include "LazyStringMapTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/share/LazyStringMap.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace share {
|
||||
|
||||
|
@ -32,130 +32,291 @@
|
||||
#include "oatpp-test/Checker.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace share {
|
||||
|
||||
namespace {
|
||||
typedef oatpp::data::share::MemoryLabel MemoryLabel;
|
||||
typedef oatpp::data::share::StringKeyLabel StringKeyLabel;
|
||||
typedef oatpp::data::share::StringKeyLabelCI StringKeyLabelCI;
|
||||
typedef oatpp::data::share::StringKeyLabelCI_FAST StringKeyLabelCI_FAST;
|
||||
}
|
||||
|
||||
void MemoryLabelTest::onRun() {
|
||||
|
||||
oatpp::String sharedData = "big text goes here";
|
||||
oatpp::String key1 = "key1";
|
||||
oatpp::String key2 = "key2";
|
||||
oatpp::String key3 = "key3";
|
||||
oatpp::String key4 = "key4";
|
||||
|
||||
std::unordered_map<oatpp::data::share::StringKeyLabel, oatpp::data::share::MemoryLabel> stringMap;
|
||||
std::unordered_map<oatpp::data::share::StringKeyLabelCI, oatpp::data::share::MemoryLabel> stringMapCI;
|
||||
std::unordered_map<oatpp::data::share::StringKeyLabelCI_FAST, oatpp::data::share::MemoryLabel> stringMapCI_FAST;
|
||||
|
||||
// Case-Sensitive
|
||||
|
||||
stringMap[key1] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[0], 3);
|
||||
stringMap[key2] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[4], 4);
|
||||
stringMap[key3] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[9], 4);
|
||||
stringMap[key4] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[14], 4);
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMap["key1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMap["key2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMap["key3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMap["key4"].getData(), 4));
|
||||
|
||||
OATPP_ASSERT(stringMap.find("Key1") == stringMap.end());
|
||||
OATPP_ASSERT(stringMap.find("Key2") == stringMap.end());
|
||||
OATPP_ASSERT(stringMap.find("Key3") == stringMap.end());
|
||||
OATPP_ASSERT(stringMap.find("Key4") == stringMap.end());
|
||||
|
||||
|
||||
// CI
|
||||
|
||||
stringMapCI[key1] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[0], 3);
|
||||
stringMapCI[key2] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[4], 4);
|
||||
stringMapCI[key3] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[9], 4);
|
||||
stringMapCI[key4] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[14], 4);
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI["key1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI["key2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI["key3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI["key4"].getData(), 4));
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI["KEY1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI["KEY2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI["KEY3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI["KEY4"].getData(), 4));
|
||||
|
||||
|
||||
// CI_FAST
|
||||
|
||||
stringMapCI_FAST[key1] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[0], 3);
|
||||
stringMapCI_FAST[key2] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[4], 4);
|
||||
stringMapCI_FAST[key3] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[9], 4);
|
||||
stringMapCI_FAST[key4] = oatpp::data::share::MemoryLabel(sharedData.getPtr(), &sharedData->getData()[14], 4);
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI_FAST["key1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI_FAST["key2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI_FAST["key3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI_FAST["key4"].getData(), 4));
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI_FAST["KEY1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI_FAST["KEY2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI_FAST["KEY3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI_FAST["KEY4"].getData(), 4));
|
||||
|
||||
{
|
||||
|
||||
v_int32 iterationsCount = 100;
|
||||
|
||||
oatpp::String headersText =
|
||||
"header0: value0\r\n"
|
||||
"header1: value1\r\n"
|
||||
"header2: value2\r\n"
|
||||
"header3: value3\r\n"
|
||||
"header4: value4\r\n"
|
||||
"header5: value5\r\n"
|
||||
"header6: value6\r\n"
|
||||
"header7: value7\r\n"
|
||||
"header8: value8\r\n"
|
||||
"header9: value9\r\n"
|
||||
"\r\n";
|
||||
|
||||
{
|
||||
|
||||
oatpp::test::PerformanceChecker timer("timer");
|
||||
|
||||
for(v_int32 i = 0; i < iterationsCount; i ++) {
|
||||
|
||||
oatpp::parser::Caret caret(headersText);
|
||||
oatpp::web::protocol::http::Status status;
|
||||
oatpp::web::protocol::http::Headers headers;
|
||||
oatpp::web::protocol::http::Parser::parseHeaders(headers, headersText.getPtr(), caret, status);
|
||||
|
||||
OATPP_ASSERT(status.code == 0);
|
||||
OATPP_ASSERT(headers.getSize() == 10);
|
||||
|
||||
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header0").equals("value0", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header1").equals("value1", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header2").equals("value2", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header3").equals("value3", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header4").equals("value4", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header5").equals("value5", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header6").equals("value6", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header7").equals("value7", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header8").equals("value8", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header9").equals("value9", 6));
|
||||
OATPP_LOGI(TAG, "StringKeyLabel default constructor...");
|
||||
StringKeyLabel s;
|
||||
StringKeyLabel s0;
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s == s0);
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("text"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabel nullptr constructor...");
|
||||
StringKeyLabel s(nullptr);
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("text"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabel const char* constructor...");
|
||||
StringKeyLabel s("hello");
|
||||
StringKeyLabel s0;
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s != s0);
|
||||
OATPP_ASSERT(s0 != s);
|
||||
OATPP_ASSERT(s == "hello");
|
||||
OATPP_ASSERT(s == oatpp::String("hello"));
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("text"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabel oatpp::String constructor...");
|
||||
StringKeyLabel s(oatpp::String("hello"));
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s == "hello");
|
||||
OATPP_ASSERT(s == oatpp::String("hello"));
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("text"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI default constructor...");
|
||||
StringKeyLabelCI s;
|
||||
StringKeyLabelCI s0;
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s == s0);
|
||||
OATPP_ASSERT(s != "teXt");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI nullptr constructor...");
|
||||
StringKeyLabelCI s(nullptr);
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s != "teXt");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI const char* constructor...");
|
||||
StringKeyLabelCI s("hello");
|
||||
StringKeyLabelCI s0;
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s != s0);
|
||||
OATPP_ASSERT(s0 != s);
|
||||
OATPP_ASSERT(s == "helLO");
|
||||
OATPP_ASSERT(s == oatpp::String("helLO"));
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI oatpp::String constructor...");
|
||||
StringKeyLabelCI s(oatpp::String("hello"));
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s == "helLO");
|
||||
OATPP_ASSERT(s == oatpp::String("helLO"));
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI_FAST default constructor...");
|
||||
StringKeyLabelCI_FAST s;
|
||||
StringKeyLabelCI_FAST s0;
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s == s0);
|
||||
OATPP_ASSERT(s != "teXt");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI_FAST nullptr constructor...");
|
||||
StringKeyLabelCI_FAST s(nullptr);
|
||||
OATPP_ASSERT(!s);
|
||||
OATPP_ASSERT(s == nullptr);
|
||||
OATPP_ASSERT(s != "teXt");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI_FAST const char* constructor...");
|
||||
StringKeyLabelCI_FAST s("hello");
|
||||
StringKeyLabelCI_FAST s0;
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s != s0);
|
||||
OATPP_ASSERT(s0 != s);
|
||||
OATPP_ASSERT(s == "helLO");
|
||||
OATPP_ASSERT(s == oatpp::String("helLO"));
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "StringKeyLabelCI_FAST oatpp::String constructor...");
|
||||
StringKeyLabelCI_FAST s(oatpp::String("hello"));
|
||||
OATPP_ASSERT(s);
|
||||
OATPP_ASSERT(s != nullptr);
|
||||
OATPP_ASSERT(s == "helLO");
|
||||
OATPP_ASSERT(s == oatpp::String("helLO"));
|
||||
OATPP_ASSERT(s != "text");
|
||||
OATPP_ASSERT(s != oatpp::String("teXt"));
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "general test...");
|
||||
|
||||
oatpp::String sharedData = "big text goes here";
|
||||
oatpp::String key1 = "key1";
|
||||
oatpp::String key2 = "key2";
|
||||
oatpp::String key3 = "key3";
|
||||
oatpp::String key4 = "key4";
|
||||
|
||||
std::unordered_map<StringKeyLabel, MemoryLabel> stringMap;
|
||||
std::unordered_map<StringKeyLabelCI, MemoryLabel> stringMapCI;
|
||||
std::unordered_map<StringKeyLabelCI_FAST, MemoryLabel> stringMapCI_FAST;
|
||||
|
||||
// Case-Sensitive
|
||||
|
||||
stringMap[key1] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[0], 3);
|
||||
stringMap[key2] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[4], 4);
|
||||
stringMap[key3] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[9], 4);
|
||||
stringMap[key4] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[14], 4);
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMap["key1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMap["key2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMap["key3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMap["key4"].getData(), 4));
|
||||
|
||||
OATPP_ASSERT(stringMap.find("Key1") == stringMap.end());
|
||||
OATPP_ASSERT(stringMap.find("Key2") == stringMap.end());
|
||||
OATPP_ASSERT(stringMap.find("Key3") == stringMap.end());
|
||||
OATPP_ASSERT(stringMap.find("Key4") == stringMap.end());
|
||||
|
||||
|
||||
// CI
|
||||
|
||||
stringMapCI[key1] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[0], 3);
|
||||
stringMapCI[key2] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[4], 4);
|
||||
stringMapCI[key3] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[9], 4);
|
||||
stringMapCI[key4] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[14], 4);
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI["key1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI["key2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI["key3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI["key4"].getData(), 4));
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI["KEY1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI["KEY2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI["KEY3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI["KEY4"].getData(), 4));
|
||||
|
||||
|
||||
// CI_FAST
|
||||
|
||||
stringMapCI_FAST[key1] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[0], 3);
|
||||
stringMapCI_FAST[key2] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[4], 4);
|
||||
stringMapCI_FAST[key3] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[9], 4);
|
||||
stringMapCI_FAST[key4] = MemoryLabel(sharedData.getPtr(), &sharedData->getData()[14], 4);
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI_FAST["key1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI_FAST["key2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI_FAST["key3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI_FAST["key4"].getData(), 4));
|
||||
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("big", stringMapCI_FAST["KEY1"].getData(), 3));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("text", stringMapCI_FAST["KEY2"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("goes", stringMapCI_FAST["KEY3"].getData(), 4));
|
||||
OATPP_ASSERT(oatpp::base::StrBuffer::equals("here", stringMapCI_FAST["KEY4"].getData(), 4));
|
||||
|
||||
{
|
||||
|
||||
v_int32 iterationsCount = 100;
|
||||
|
||||
oatpp::String headersText =
|
||||
"header0: value0\r\n"
|
||||
"header1: value1\r\n"
|
||||
"header2: value2\r\n"
|
||||
"header3: value3\r\n"
|
||||
"header4: value4\r\n"
|
||||
"header5: value5\r\n"
|
||||
"header6: value6\r\n"
|
||||
"header7: value7\r\n"
|
||||
"header8: value8\r\n"
|
||||
"header9: value9\r\n"
|
||||
"\r\n";
|
||||
|
||||
{
|
||||
|
||||
oatpp::test::PerformanceChecker timer("timer");
|
||||
|
||||
for (v_int32 i = 0; i < iterationsCount; i++) {
|
||||
|
||||
oatpp::parser::Caret caret(headersText);
|
||||
oatpp::web::protocol::http::Status status;
|
||||
oatpp::web::protocol::http::Headers headers;
|
||||
oatpp::web::protocol::http::Parser::parseHeaders(headers, headersText.getPtr(), caret, status);
|
||||
|
||||
OATPP_ASSERT(status.code == 0);
|
||||
OATPP_ASSERT(headers.getSize() == 10);
|
||||
|
||||
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header0").equals("value0", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header1").equals("value1", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header2").equals("value2", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header3").equals("value3", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header4").equals("value4", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header5").equals("value5", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header6").equals("value6", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header7").equals("value7", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header8").equals("value8", 6));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header9").equals("value9", 6));
|
||||
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header0").equals("value0"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header1").equals("value1"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header2").equals("value2"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header3").equals("value3"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header4").equals("value4"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header5").equals("value5"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header6").equals("value6"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header7").equals("value7"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header8").equals("value8"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<StringKeyLabel>("header9").equals("value9"));
|
||||
|
||||
}
|
||||
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header0").equals("value0"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header1").equals("value1"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header2").equals("value2"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header3").equals("value3"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header4").equals("value4"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header5").equals("value5"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header6").equals("value6"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header7").equals("value7"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header8").equals("value8"));
|
||||
OATPP_ASSERT(headers.getAsMemoryLabel<oatpp::data::share::StringKeyLabel>("header9").equals("value9"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,16 +50,16 @@ typedef oatpp::parser::json::mapping::Deserializer Deserializer;
|
||||
|
||||
DTO_FIELD(String, field_string);
|
||||
DTO_FIELD(Int32, field_int32);
|
||||
DTO_FIELD(List<Int32>::ObjectWrapper, field_list);
|
||||
DTO_FIELD(List<Int32>, field_list);
|
||||
|
||||
static ObjectWrapper createTestInstance(){
|
||||
auto result = Test1::createShared();
|
||||
result->field_string = "String Field";
|
||||
result->field_int32 = 5;
|
||||
result->field_list = List<Int32>::createShared();
|
||||
result->field_list->pushBack(1);
|
||||
result->field_list->pushBack(2);
|
||||
result->field_list->pushBack(3);
|
||||
result->field_list->push_back(1);
|
||||
result->field_list->push_back(2);
|
||||
result->field_list->push_back(3);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "oatpp/core/data/mapping/type/List.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Primitive.hpp"
|
||||
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
@ -38,11 +40,9 @@ namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
typedef oatpp::data::mapping::type::Object DTO;
|
||||
class TestChild : public oatpp::Object {
|
||||
|
||||
class TestChild : public DTO {
|
||||
|
||||
DTO_INIT(TestChild, DTO)
|
||||
DTO_INIT(TestChild, Object)
|
||||
|
||||
static ObjectWrapper createShared(const char* name, const char* secondName){
|
||||
auto result = createShared();
|
||||
@ -56,9 +56,9 @@ class TestChild : public DTO {
|
||||
|
||||
};
|
||||
|
||||
class Test : public DTO {
|
||||
class Test : public oatpp::Object {
|
||||
|
||||
DTO_INIT(Test, DTO)
|
||||
DTO_INIT(Test, Object)
|
||||
|
||||
DTO_FIELD(String, field_string, "string-field-name-qualifier");
|
||||
DTO_FIELD(Int32, field_int32, "int32-field-name-qualifier");
|
||||
@ -67,20 +67,41 @@ class Test : public DTO {
|
||||
DTO_FIELD(Float64, field_float64);
|
||||
DTO_FIELD(Boolean, field_boolean);
|
||||
|
||||
DTO_FIELD(List<String>::ObjectWrapper, field_list_string) = List<String>::createShared();
|
||||
DTO_FIELD(List<Int32>::ObjectWrapper, field_list_int32) = List<Int32>::createShared();
|
||||
DTO_FIELD(List<Int64>::ObjectWrapper, field_list_int64) = List<Int64>::createShared();
|
||||
DTO_FIELD(List<Float32>::ObjectWrapper, field_list_float32) = List<Float32>::createShared();
|
||||
DTO_FIELD(List<Float64>::ObjectWrapper, field_list_float64) = List<Float64>::createShared();
|
||||
DTO_FIELD(List<Boolean>::ObjectWrapper, field_list_boolean) = List<Boolean>::createShared();
|
||||
DTO_FIELD(List<String>, field_list_string) = List<String>::createShared();
|
||||
DTO_FIELD(List<Int32>, field_list_int32) = List<Int32>::createShared();
|
||||
DTO_FIELD(List<Int64>, field_list_int64) = List<Int64>::createShared();
|
||||
DTO_FIELD(List<Float32>, field_list_float32) = List<Float32>::createShared();
|
||||
DTO_FIELD(List<Float64>, field_list_float64) = List<Float64>::createShared();
|
||||
DTO_FIELD(List<Boolean>, field_list_boolean) = List<Boolean>::createShared();
|
||||
|
||||
DTO_FIELD(List<TestChild::ObjectWrapper>::ObjectWrapper, field_list_object) = List<TestChild::ObjectWrapper>::createShared();
|
||||
DTO_FIELD(List<List<TestChild::ObjectWrapper>::ObjectWrapper>::ObjectWrapper, field_list_list_object) = List<List<TestChild::ObjectWrapper>::ObjectWrapper>::createShared();
|
||||
DTO_FIELD(List<TestChild>, field_list_object) = List<TestChild>::createShared();
|
||||
DTO_FIELD(List<List<TestChild>>, field_list_list_object) = List<List<TestChild>>::createShared();
|
||||
|
||||
DTO_FIELD(Vector<String>, field_vector);
|
||||
DTO_FIELD(Fields<String>, field_fields);
|
||||
DTO_FIELD(UnorderedFields<String>, field_unordered_fields);
|
||||
|
||||
DTO_FIELD(Test::ObjectWrapper, obj1);
|
||||
DTO_FIELD(TestChild::ObjectWrapper, child1);
|
||||
DTO_FIELD(Test, obj1);
|
||||
DTO_FIELD(TestChild, child1);
|
||||
|
||||
};
|
||||
|
||||
class TestAny : public oatpp::Object {
|
||||
|
||||
DTO_INIT(TestAny, Object)
|
||||
|
||||
DTO_FIELD(List<Any>, anyList) = List<Any>::createShared();
|
||||
|
||||
};
|
||||
|
||||
class TestAnyNested : public oatpp::Object {
|
||||
|
||||
DTO_INIT(TestAnyNested, Object)
|
||||
|
||||
DTO_FIELD(String, f1) = "Field_1";
|
||||
DTO_FIELD(String, f2) = "Field_2";
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
@ -89,7 +110,8 @@ class Test : public DTO {
|
||||
void DTOMapperTest::onRun(){
|
||||
|
||||
auto mapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
|
||||
mapper->getSerializer()->getConfig()->useBeautifier = true;
|
||||
|
||||
Test::ObjectWrapper test1 = Test::createShared();
|
||||
|
||||
test1->field_string = "string value";
|
||||
@ -101,61 +123,93 @@ void DTOMapperTest::onRun(){
|
||||
|
||||
test1->obj1 = Test::createShared();
|
||||
test1->obj1->field_string = "inner string";
|
||||
test1->obj1->field_list_string->pushBack("inner str_item_1");
|
||||
test1->obj1->field_list_string->pushBack("inner str_item_2");
|
||||
test1->obj1->field_list_string->pushBack("inner str_item_3");
|
||||
test1->obj1->field_list_string->push_back("inner str_item_1");
|
||||
test1->obj1->field_list_string->push_back("inner str_item_2");
|
||||
test1->obj1->field_list_string->push_back("inner str_item_3");
|
||||
|
||||
test1->child1 = TestChild::createShared();
|
||||
test1->child1->name = "child1_name";
|
||||
test1->child1->secondName = "child1_second_name";
|
||||
|
||||
test1->field_list_string->pushBack("str_item_1");
|
||||
test1->field_list_string->pushBack("str_item_2");
|
||||
test1->field_list_string->pushBack("str_item_3");
|
||||
test1->field_list_string->push_back("str_item_1");
|
||||
test1->field_list_string->push_back("str_item_2");
|
||||
test1->field_list_string->push_back("str_item_3");
|
||||
|
||||
test1->field_list_int32->pushBack(321);
|
||||
test1->field_list_int32->pushBack(322);
|
||||
test1->field_list_int32->pushBack(323);
|
||||
test1->field_list_int32->push_back(321);
|
||||
test1->field_list_int32->push_back(322);
|
||||
test1->field_list_int32->push_back(323);
|
||||
|
||||
test1->field_list_int64->pushBack(641);
|
||||
test1->field_list_int64->pushBack(642);
|
||||
test1->field_list_int64->pushBack(643);
|
||||
test1->field_list_int64->push_back(641);
|
||||
test1->field_list_int64->push_back(642);
|
||||
test1->field_list_int64->push_back(643);
|
||||
|
||||
test1->field_list_float32->pushBack(0.321f);
|
||||
test1->field_list_float32->pushBack(0.322f);
|
||||
test1->field_list_float32->pushBack(0.323f);
|
||||
test1->field_list_float32->push_back(0.321f);
|
||||
test1->field_list_float32->push_back(0.322f);
|
||||
test1->field_list_float32->push_back(0.323f);
|
||||
|
||||
test1->field_list_float64->pushBack(0.641);
|
||||
test1->field_list_float64->pushBack(0.642);
|
||||
test1->field_list_float64->pushBack(0.643);
|
||||
test1->field_list_float64->push_back(0.641);
|
||||
test1->field_list_float64->push_back(0.642);
|
||||
test1->field_list_float64->push_back(0.643);
|
||||
|
||||
test1->field_list_boolean->pushBack(true);
|
||||
test1->field_list_boolean->pushBack(false);
|
||||
test1->field_list_boolean->pushBack(true);
|
||||
test1->field_list_boolean->push_back(true);
|
||||
test1->field_list_boolean->push_back(false);
|
||||
test1->field_list_boolean->push_back(true);
|
||||
|
||||
test1->field_list_object->pushBack(TestChild::createShared("child", "1"));
|
||||
test1->field_list_object->pushBack(TestChild::createShared("child", "2"));
|
||||
test1->field_list_object->pushBack(TestChild::createShared("child", "3"));
|
||||
test1->field_list_object->push_back(TestChild::createShared("child", "1"));
|
||||
test1->field_list_object->push_back(TestChild::createShared("child", "2"));
|
||||
test1->field_list_object->push_back(TestChild::createShared("child", "3"));
|
||||
|
||||
auto l1 = DTO::List<TestChild::ObjectWrapper>::createShared();
|
||||
auto l2 = DTO::List<TestChild::ObjectWrapper>::createShared();
|
||||
auto l3 = DTO::List<TestChild::ObjectWrapper>::createShared();
|
||||
auto l1 = oatpp::List<TestChild>::createShared();
|
||||
auto l2 = oatpp::List<TestChild>::createShared();
|
||||
auto l3 = oatpp::List<TestChild>::createShared();
|
||||
|
||||
l1->pushBack(TestChild::createShared("list_1", "item_1"));
|
||||
l1->pushBack(TestChild::createShared("list_1", "item_2"));
|
||||
l1->pushBack(TestChild::createShared("list_1", "item_3"));
|
||||
l1->push_back(TestChild::createShared("list_1", "item_1"));
|
||||
l1->push_back(TestChild::createShared("list_1", "item_2"));
|
||||
l1->push_back(TestChild::createShared("list_1", "item_3"));
|
||||
|
||||
l2->pushBack(TestChild::createShared("list_2", "item_1"));
|
||||
l2->pushBack(TestChild::createShared("list_2", "item_2"));
|
||||
l2->pushBack(TestChild::createShared("list_2", "item_3"));
|
||||
l2->push_back(TestChild::createShared("list_2", "item_1"));
|
||||
l2->push_back(TestChild::createShared("list_2", "item_2"));
|
||||
l2->push_back(TestChild::createShared("list_2", "item_3"));
|
||||
|
||||
l3->pushBack(TestChild::createShared("list_3", "item_1"));
|
||||
l3->pushBack(TestChild::createShared("list_3", "item_2"));
|
||||
l3->pushBack(TestChild::createShared("list_3", "item_3"));
|
||||
l3->push_back(TestChild::createShared("list_3", "item_1"));
|
||||
l3->push_back(TestChild::createShared("list_3", "item_2"));
|
||||
l3->push_back(TestChild::createShared("list_3", "item_3"));
|
||||
|
||||
test1->field_list_list_object->pushBack(l1);
|
||||
test1->field_list_list_object->pushBack(l2);
|
||||
test1->field_list_list_object->pushBack(l3);
|
||||
test1->field_list_list_object->push_back(l1);
|
||||
test1->field_list_list_object->push_back(l2);
|
||||
test1->field_list_list_object->push_back(l3);
|
||||
|
||||
test1->field_vector = {"vector_item1", "vector_item2", "vector_item3"};
|
||||
|
||||
test1->field_fields = {
|
||||
{"key0", "pair_item0"},
|
||||
{"key1", "pair_item1"},
|
||||
{"key2", "pair_item2"},
|
||||
{"key3", "pair_item3"},
|
||||
{"key4", "pair_item4"},
|
||||
{"key5", "pair_item5"},
|
||||
{"key6", "pair_item6"},
|
||||
{"key7", "pair_item7"},
|
||||
{"key8", "pair_item8"},
|
||||
{"key9", "pair_item9"},
|
||||
{"key10", "pair_item10"},
|
||||
{"key11", "pair_item11"}
|
||||
};
|
||||
|
||||
test1->field_unordered_fields = {
|
||||
{"key0", "map_item0"},
|
||||
{"key1", "map_item1"},
|
||||
{"key2", "map_item2"},
|
||||
{"key3", "map_item3"},
|
||||
{"key4", "map_item4"},
|
||||
{"key5", "map_item5"},
|
||||
{"key6", "map_item6"},
|
||||
{"key7", "map_item7"},
|
||||
{"key8", "map_item8"},
|
||||
{"key9", "map_item9"},
|
||||
{"key10", "map_item10"},
|
||||
{"key11", "map_item11"}
|
||||
};
|
||||
|
||||
auto result = mapper->writeToString(test1);
|
||||
|
||||
@ -172,24 +226,80 @@ void DTOMapperTest::onRun(){
|
||||
OATPP_ASSERT(obj->field_string == test1->field_string);
|
||||
|
||||
OATPP_ASSERT(obj->field_int32);
|
||||
OATPP_ASSERT(obj->field_int32->getValue() == test1->field_int32->getValue());
|
||||
OATPP_ASSERT(obj->field_int32 == test1->field_int32);
|
||||
|
||||
OATPP_ASSERT(obj->field_int64);
|
||||
OATPP_ASSERT(obj->field_int64->getValue() == test1->field_int64->getValue());
|
||||
OATPP_ASSERT(obj->field_int64 == test1->field_int64);
|
||||
|
||||
OATPP_ASSERT(obj->field_float32);
|
||||
OATPP_ASSERT(obj->field_float32->getValue() == test1->field_float32->getValue());
|
||||
OATPP_ASSERT(obj->field_float32 == test1->field_float32);
|
||||
|
||||
OATPP_ASSERT(obj->field_float64);
|
||||
OATPP_ASSERT(obj->field_float64->getValue() == test1->field_float64->getValue());
|
||||
OATPP_ASSERT(obj->field_float64 == test1->field_float64);
|
||||
|
||||
OATPP_ASSERT(obj->field_boolean);
|
||||
OATPP_ASSERT(obj->field_boolean->getValue() == test1->field_boolean->getValue());
|
||||
OATPP_ASSERT(obj->field_boolean == test1->field_boolean);
|
||||
|
||||
{
|
||||
auto c = obj->field_vector;
|
||||
OATPP_ASSERT(c[0] == "vector_item1");
|
||||
OATPP_ASSERT(c[1] == "vector_item2");
|
||||
OATPP_ASSERT(c[2] == "vector_item3");
|
||||
}
|
||||
|
||||
{
|
||||
auto c = obj->field_fields;
|
||||
v_int32 i = 0;
|
||||
for(auto& pair : *c) {
|
||||
OATPP_ASSERT(pair.first == "key" + oatpp::utils::conversion::int32ToStr(i));
|
||||
OATPP_ASSERT(pair.second == "pair_item" + oatpp::utils::conversion::int32ToStr(i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto c = obj->field_unordered_fields;
|
||||
OATPP_ASSERT(c["key1"] == "map_item1");
|
||||
OATPP_ASSERT(c["key2"] == "map_item2");
|
||||
OATPP_ASSERT(c["key3"] == "map_item3");
|
||||
}
|
||||
|
||||
result = mapper->writeToString(obj);
|
||||
|
||||
OATPP_LOGV(TAG, "json='%s'", (const char*) result->getData());
|
||||
|
||||
{
|
||||
|
||||
TestAny::ObjectWrapper::__Wrapper objOW1;
|
||||
TestAny::__Wrapper objOW2;
|
||||
|
||||
auto obj = TestAny::createShared();
|
||||
obj->anyList = {
|
||||
oatpp::String("Hello Any!!!"),
|
||||
oatpp::Int32(32),
|
||||
oatpp::Int64(64),
|
||||
oatpp::Float64(0.64),
|
||||
oatpp::Float64(0.64),
|
||||
TestAnyNested::createShared()
|
||||
};
|
||||
|
||||
auto map = oatpp::Fields<Any>::createShared();
|
||||
map["bool-field"] = oatpp::Boolean(false);
|
||||
map["vector"] = oatpp::Vector<oatpp::String>({"vector_v1", "vector_v2", "vector_v3"});
|
||||
map["unordered_map"] = oatpp::UnorderedFields<oatpp::String>({{"key1", "value1"}, {"key2", "value2"}});
|
||||
|
||||
obj->anyList->push_back(map);
|
||||
|
||||
auto json = mapper->writeToString(obj);
|
||||
OATPP_LOGV(TAG, "any json='%s'", (const char*) json->getData());
|
||||
|
||||
auto deserializedAny = mapper->readFromString<oatpp::Fields<oatpp::Any>>(json);
|
||||
|
||||
auto json2 = mapper->writeToString(deserializedAny);
|
||||
OATPP_LOGV(TAG, "any json='%s'", (const char*) json2->getData());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
@ -72,9 +72,9 @@ class Test4 : public DTO {
|
||||
|
||||
DTO_INIT(Test4, DTO)
|
||||
|
||||
DTO_FIELD(EmptyDto::ObjectWrapper, object);
|
||||
DTO_FIELD(List<EmptyDto::ObjectWrapper>::ObjectWrapper, list);
|
||||
DTO_FIELD(Fields<EmptyDto::ObjectWrapper>::ObjectWrapper, map);
|
||||
DTO_FIELD(EmptyDto, object);
|
||||
DTO_FIELD(List<EmptyDto>, list);
|
||||
DTO_FIELD(Fields<EmptyDto>, map);
|
||||
|
||||
};
|
||||
|
||||
@ -111,12 +111,12 @@ void DeserializerTest::onRun(){
|
||||
obj2 = mapper->readFromString<Test2>("{\"int32F\": 32}");
|
||||
|
||||
OATPP_ASSERT(obj2);
|
||||
OATPP_ASSERT(obj2->int32F->getValue() == 32);
|
||||
OATPP_ASSERT(obj2->int32F == 32);
|
||||
|
||||
obj2 = mapper->readFromString<Test2>("{\"int32F\": -32}");
|
||||
|
||||
OATPP_ASSERT(obj2);
|
||||
OATPP_ASSERT(obj2->int32F->getValue() == -32);
|
||||
OATPP_ASSERT(obj2->int32F == -32);
|
||||
|
||||
auto obj3 = mapper->readFromString<Test3>("{\"float32F\": null}");
|
||||
|
||||
@ -126,7 +126,7 @@ void DeserializerTest::onRun(){
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": 32}");
|
||||
|
||||
OATPP_ASSERT(obj3);
|
||||
OATPP_ASSERT(obj3->float32F->getValue() == 32);
|
||||
OATPP_ASSERT(obj3->float32F == 32);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": 1.32e1}");
|
||||
|
||||
@ -155,10 +155,10 @@ void DeserializerTest::onRun(){
|
||||
|
||||
auto list = mapper->readFromString<Test1::List<Test1::Int32>>("[1, 2, 3]");
|
||||
OATPP_ASSERT(list);
|
||||
OATPP_ASSERT(list->count() == 3);
|
||||
OATPP_ASSERT(list->get(0)->getValue() == 1);
|
||||
OATPP_ASSERT(list->get(1)->getValue() == 2);
|
||||
OATPP_ASSERT(list->get(2)->getValue() == 3);
|
||||
OATPP_ASSERT(list->size() == 3);
|
||||
OATPP_ASSERT(list[0] == 1);
|
||||
OATPP_ASSERT(list[1] == 2);
|
||||
OATPP_ASSERT(list[2] == 3);
|
||||
|
||||
// Empty test
|
||||
|
||||
@ -166,15 +166,15 @@ void DeserializerTest::onRun(){
|
||||
OATPP_ASSERT(obj4);
|
||||
OATPP_ASSERT(obj4->object);
|
||||
OATPP_ASSERT(obj4->list);
|
||||
OATPP_ASSERT(obj4->list->count() == 0);
|
||||
OATPP_ASSERT(obj4->map->count() == 0);
|
||||
OATPP_ASSERT(obj4->list->size() == 0);
|
||||
OATPP_ASSERT(obj4->map->size() == 0);
|
||||
|
||||
obj4 = mapper->readFromString<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->count() == 0);
|
||||
OATPP_ASSERT(obj4->map->count() == 0);
|
||||
OATPP_ASSERT(obj4->list->size() == 0);
|
||||
OATPP_ASSERT(obj4->map->size() == 0);
|
||||
|
||||
}
|
||||
|
||||
|
187
test/oatpp/parser/json/mapping/EnumTest.cpp
Normal file
187
test/oatpp/parser/json/mapping/EnumTest.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "EnumTest.hpp"
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
ENUM(Enum0, v_int32);
|
||||
|
||||
ENUM(Enum1, v_int32,
|
||||
VALUE(V1, 10, "enum1-v1"),
|
||||
VALUE(V2, 20, "enum1-v2"),
|
||||
VALUE(V3, 30, "enum1-v3")
|
||||
);
|
||||
|
||||
class DTO1 : public oatpp::Object {
|
||||
|
||||
DTO_INIT(DTO1, Object)
|
||||
|
||||
DTO_FIELD(Enum<Enum1>::AsString, enum1);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
void EnumTest::onRun() {
|
||||
|
||||
oatpp::parser::json::mapping::ObjectMapper mapper;
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Serializer as string...");
|
||||
oatpp::Fields<oatpp::Enum<Enum1>::AsString> map = {{"enum", Enum1::V1}};
|
||||
auto json = mapper.writeToString(map);
|
||||
OATPP_LOGD(TAG, "json='%s'", json->c_str());
|
||||
OATPP_ASSERT(json == "{\"enum\":\"enum1-v1\"}");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Serializer as string null...");
|
||||
oatpp::Fields<oatpp::Enum<Enum1>::AsString> map = {{"enum", nullptr}};
|
||||
auto json = mapper.writeToString(map);
|
||||
OATPP_LOGD(TAG, "json='%s'", json->c_str());
|
||||
OATPP_ASSERT(json == "{\"enum\":null}");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Serializer as string error on null...");
|
||||
bool error = false;
|
||||
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());
|
||||
error = true;
|
||||
}
|
||||
OATPP_ASSERT(error == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Serializer as int...");
|
||||
oatpp::Fields<oatpp::Enum<Enum1>::AsNumber> map = {{"enum", Enum1::V1}};
|
||||
auto json = mapper.writeToString(map);
|
||||
OATPP_LOGD(TAG, "json='%s'", json->c_str());
|
||||
OATPP_ASSERT(json == "{\"enum\":10}");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Serializer as int null...");
|
||||
oatpp::Fields<oatpp::Enum<Enum1>::AsNumber> map = {{"enum", nullptr}};
|
||||
auto json = mapper.writeToString(map);
|
||||
OATPP_LOGD(TAG, "json='%s'", json->c_str());
|
||||
OATPP_ASSERT(json == "{\"enum\":null}");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Serializer as int error on null...");
|
||||
bool error = false;
|
||||
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());
|
||||
error = true;
|
||||
}
|
||||
OATPP_ASSERT(error == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Deserializer as string...");
|
||||
oatpp::String json = "{\"enum\":\"enum1-v2\"}";
|
||||
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsString>>(json);
|
||||
OATPP_ASSERT(map["enum"] == Enum1::V2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Deserializer as string null...");
|
||||
oatpp::String json = "{\"enum\":null}";
|
||||
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsString>>(json);
|
||||
OATPP_ASSERT(map["enum"] == nullptr);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Deserializer as string error on null...");
|
||||
bool error = false;
|
||||
oatpp::String json = "{\"enum\":null}";
|
||||
try {
|
||||
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsString::NotNull>>(json);
|
||||
} catch (const oatpp::parser::ParsingError& e) {
|
||||
OATPP_LOGD(TAG, "error - %s", e.what());
|
||||
error = true;
|
||||
}
|
||||
OATPP_ASSERT(error == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Deserializer as int...");
|
||||
oatpp::String json = "{\"enum\":20}";
|
||||
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsNumber>>(json);
|
||||
OATPP_ASSERT(map["enum"] == Enum1::V2);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Deserializer as int null...");
|
||||
oatpp::String json = "{\"enum\":null}";
|
||||
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsNumber>>(json);
|
||||
OATPP_ASSERT(map["enum"] == nullptr);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Deserializer as int error on null...");
|
||||
bool error = false;
|
||||
oatpp::String json = "{\"enum\":null}";
|
||||
try {
|
||||
auto map = mapper.readFromString<oatpp::Fields<oatpp::Enum<Enum1>::AsNumber::NotNull>>(json);
|
||||
} catch (const oatpp::parser::ParsingError& e) {
|
||||
OATPP_LOGD(TAG, "error - %s", e.what());
|
||||
error = true;
|
||||
}
|
||||
OATPP_ASSERT(error == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}
|
@ -22,21 +22,21 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_test_base_RegRuleTest_hpp
|
||||
#define oatpp_test_base_RegRuleTest_hpp
|
||||
#ifndef oatpp_test_parser_json_mapping_EnumTest_hpp
|
||||
#define oatpp_test_parser_json_mapping_EnumTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace base {
|
||||
|
||||
class RegRuleTest : public UnitTest{
|
||||
public:
|
||||
|
||||
RegRuleTest():UnitTest("TEST[base::RegRuleTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
#endif /* oatpp_test_base_RegRuleTest_hpp */
|
||||
class EnumTest : public UnitTest{
|
||||
public:
|
||||
|
||||
EnumTest():UnitTest("TEST[parser::json::mapping::EnumTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
|
||||
#endif /* oatpp_test_parser_json_mapping_EnumTest_hpp */
|
53
test/oatpp/parser/json/mapping/UnorderedSetTest.cpp
Normal file
53
test/oatpp/parser/json/mapping/UnorderedSetTest.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "UnorderedSetTest.hpp"
|
||||
|
||||
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
void UnorderedSetTest::onRun() {
|
||||
|
||||
oatpp::parser::json::mapping::ObjectMapper mapper;
|
||||
|
||||
{
|
||||
oatpp::UnorderedSet<oatpp::String> set = {"Hello", "World", "!"};
|
||||
auto json = mapper.writeToString(set);
|
||||
OATPP_LOGD(TAG, "json='%s'", json->c_str());
|
||||
}
|
||||
|
||||
{
|
||||
oatpp::String json = "[\"Hello\",\"World\",\"!\",\"Hello\",\"World\",\"!\"]";
|
||||
auto set = mapper.readFromString<oatpp::UnorderedSet<oatpp::String>>(json);
|
||||
OATPP_ASSERT(set);
|
||||
OATPP_ASSERT(set->size() == 3);
|
||||
for(auto& item : *set) {
|
||||
OATPP_LOGD(TAG, "item='%s'", item->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}
|
42
test/oatpp/parser/json/mapping/UnorderedSetTest.hpp
Normal file
42
test/oatpp/parser/json/mapping/UnorderedSetTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_test_parser_json_mapping_UnorderedSetTest_hpp
|
||||
#define oatpp_test_parser_json_mapping_UnorderedSetTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
class UnorderedSetTest : public UnitTest{
|
||||
public:
|
||||
|
||||
UnorderedSetTest():UnitTest("TEST[parser::json::mapping::UnorderedSetTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
|
||||
#endif /* oatpp_test_parser_json_mapping_UnorderedSetTest_hpp */
|
@ -270,10 +270,10 @@ void FullTest::onRun() {
|
||||
auto dto = response->readBodyToDto<app::TestDto>(objectMapper.get());
|
||||
OATPP_ASSERT(dto);
|
||||
OATPP_ASSERT(dto->testMap);
|
||||
OATPP_ASSERT(dto->testMap->count() == 3);
|
||||
OATPP_ASSERT(dto->testMap->get("key1", "") == "value1");
|
||||
OATPP_ASSERT(dto->testMap->get("key2", "") == "32");
|
||||
OATPP_ASSERT(dto->testMap->get("key3", "") == oatpp::utils::conversion::float32ToStr(0.32f));
|
||||
OATPP_ASSERT(dto->testMap->size() == 3);
|
||||
OATPP_ASSERT(dto->testMap["key1"] == "value1");
|
||||
OATPP_ASSERT(dto->testMap["key2"] == "32");
|
||||
OATPP_ASSERT(dto->testMap["key3"] == oatpp::utils::conversion::float32ToStr(0.32f));
|
||||
}
|
||||
|
||||
{ // test GET with header parameter
|
||||
@ -299,7 +299,19 @@ void FullTest::onRun() {
|
||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||
auto dtoOut = response->readBodyToDto<app::TestDto>(objectMapper.get());
|
||||
OATPP_ASSERT(dtoOut);
|
||||
OATPP_ASSERT(dtoOut->testValueInt->getValue() == i);
|
||||
OATPP_ASSERT(dtoOut->testValueInt == i);
|
||||
}
|
||||
|
||||
{ // test Enum as String
|
||||
oatpp::Enum<app::AllowedPathParams> v = app::AllowedPathParams::HELLO;
|
||||
auto response = client->getHeaderEnumAsString(v);
|
||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||
}
|
||||
|
||||
{ // test Enum as String
|
||||
oatpp::Enum<app::AllowedPathParams> v = app::AllowedPathParams::HELLO;
|
||||
auto response = client->getHeaderEnumAsNumber(v);
|
||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||
}
|
||||
|
||||
{ // test Big Echo with body
|
||||
|
@ -55,7 +55,11 @@ public:
|
||||
API_CALL("GET", "queries/map", getWithQueriesMap, QUERY(String, key1), QUERY(Int32, key2), QUERY(Float32, key3))
|
||||
API_CALL("GET", "headers", getWithHeaders, HEADER(String, param, "X-TEST-HEADER"))
|
||||
API_CALL("POST", "body", postBody, BODY_STRING(String, body))
|
||||
API_CALL("POST", "body-dto", postBodyDto, BODY_DTO(TestDto::ObjectWrapper, body))
|
||||
API_CALL("POST", "body-dto", postBodyDto, BODY_DTO(TestDto, body))
|
||||
|
||||
API_CALL("GET", "enum/as-string", getHeaderEnumAsString, HEADER(Enum<AllowedPathParams>::AsString, enumValue, "enum"))
|
||||
API_CALL("GET", "enum/as-number", getHeaderEnumAsNumber, HEADER(Enum<AllowedPathParams>::AsNumber, enumValue, "enum"))
|
||||
|
||||
API_CALL("POST", "echo", echoBody, BODY_STRING(String, body))
|
||||
API_CALL("GET", "header-value-set", headerValueSet, HEADER(String, valueSet, "X-VALUE-SET"))
|
||||
|
||||
|
@ -109,16 +109,16 @@ public:
|
||||
ENDPOINT("GET", "queries", getWithQueries,
|
||||
QUERY(String, name), QUERY(Int32, age)) {
|
||||
auto dto = TestDto::createShared();
|
||||
dto->testValue = "name=" + name + "&age=" + oatpp::utils::conversion::int32ToStr(age->getValue());
|
||||
dto->testValue = "name=" + name + "&age=" + oatpp::utils::conversion::int32ToStr(*age);
|
||||
return createDtoResponse(Status::CODE_200, dto);
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "queries/map", getWithQueriesMap,
|
||||
QUERIES(QueryParams, queries)) {
|
||||
auto dto = TestDto::createShared();
|
||||
dto->testMap = dto->testMap->createShared();
|
||||
dto->testMap = dto->testMap.createShared();
|
||||
for(auto& it : queries.getAll()) {
|
||||
dto->testMap->put(it.first.toString(), it.second.toString());
|
||||
dto->testMap[it.first.toString()] = it.second.toString();
|
||||
}
|
||||
return createDtoResponse(Status::CODE_200, dto);
|
||||
}
|
||||
@ -140,7 +140,7 @@ public:
|
||||
}
|
||||
|
||||
ENDPOINT("POST", "body-dto", postBodyDto,
|
||||
BODY_DTO(TestDto::ObjectWrapper, body)) {
|
||||
BODY_DTO(TestDto, body)) {
|
||||
//OATPP_LOGV(TAG, "POST body %s", body->c_str());
|
||||
return createDtoResponse(Status::CODE_200, body);
|
||||
}
|
||||
@ -216,7 +216,7 @@ public:
|
||||
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||
{
|
||||
auto body = std::make_shared<oatpp::web::protocol::http::outgoing::StreamingBody>
|
||||
(std::make_shared<ReadCallback>(text, numIterations->getValue()));
|
||||
(std::make_shared<ReadCallback>(text, *numIterations));
|
||||
return OutgoingResponse::createShared(Status::CODE_200, body);
|
||||
}
|
||||
|
||||
@ -282,6 +282,18 @@ public:
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "enum/as-string", testEnumString,
|
||||
HEADER(Enum<AllowedPathParams>::AsString, enumValue, "enum"))
|
||||
{
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
}
|
||||
|
||||
ENDPOINT("GET", "enum/as-number", testEnumNumber,
|
||||
HEADER(Enum<AllowedPathParams>::AsNumber, enumValue, "enum"))
|
||||
{
|
||||
return createResponse(Status::CODE_200, "OK");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -38,10 +38,15 @@ class TestDto : public oatpp::data::mapping::type::Object {
|
||||
|
||||
DTO_FIELD(String, testValue);
|
||||
DTO_FIELD(Int32, testValueInt);
|
||||
DTO_FIELD(Fields<String>::ObjectWrapper, testMap);
|
||||
DTO_FIELD(Fields<String>, testMap);
|
||||
|
||||
};
|
||||
|
||||
ENUM(AllowedPathParams, v_int32,
|
||||
VALUE(HELLO, 100, "hello"),
|
||||
VALUE(WORLD, 200, "world")
|
||||
)
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}}}}
|
||||
|
Loading…
Reference in New Issue
Block a user