mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2024-12-22 22:16:37 +08:00
Initial commit. Separated from lganzzzo's private repo.
This commit is contained in:
parent
8914b7d695
commit
28e6032dd9
44
core/src/base/Controllable.cpp
Normal file
44
core/src/base/Controllable.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Controllable.hpp"
|
||||
#include "Controllable.hpp"
|
||||
|
||||
namespace oatpp { namespace base{
|
||||
|
||||
const char* Controllable::TAG = "Controllable";
|
||||
|
||||
Controllable::Controllable() {
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
Environment::incObjects();
|
||||
#endif
|
||||
}
|
||||
|
||||
Controllable::~Controllable(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
Environment::decObjects();
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
53
core/src/base/Controllable.hpp
Normal file
53
core/src/base/Controllable.hpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_base_Controllable
|
||||
#define oatpp_base_Controllable
|
||||
|
||||
#include <memory>
|
||||
#include "./Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace base{
|
||||
|
||||
class Controllable : public std::enable_shared_from_this<Controllable> {
|
||||
private:
|
||||
static const char* TAG;
|
||||
public:
|
||||
template<class T>
|
||||
std::shared_ptr<T> getSharedPtr() {
|
||||
return std::static_pointer_cast<T>(shared_from_this());
|
||||
}
|
||||
public:
|
||||
Controllable();
|
||||
virtual ~Controllable();
|
||||
|
||||
static std::shared_ptr<Controllable> createShared(){
|
||||
return std::shared_ptr<Controllable>(new Controllable);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_base_Controllable */
|
204
core/src/base/Environment.cpp
Normal file
204
core/src/base/Environment.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Environment.hpp"
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace oatpp { namespace base {
|
||||
|
||||
Logger* Environment::m_logger = nullptr;
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, void*>> Environment::m_components;
|
||||
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
v_atomicCounter Environment::m_objectsCount(0);
|
||||
v_atomicCounter Environment::m_objectsCreated(0);
|
||||
thread_local v_counter Environment::m_threadLocalObjectsCount = 0;
|
||||
thread_local v_counter Environment::m_threadLocalObjectsCreated = 0;
|
||||
#endif
|
||||
|
||||
void Environment::init(){
|
||||
checkTypes();
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
m_objectsCount = 0;
|
||||
m_objectsCreated = 0;
|
||||
m_threadLocalObjectsCount = 0;
|
||||
m_threadLocalObjectsCreated = 0;
|
||||
#endif
|
||||
if(m_components.size() > 0) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Invalid state. Components were created before call to Environment::init()");
|
||||
}
|
||||
}
|
||||
|
||||
void Environment::destroy(){
|
||||
if(m_components.size() > 0) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Invalid state. Leaking components");
|
||||
}
|
||||
}
|
||||
|
||||
void Environment::checkTypes(){
|
||||
|
||||
OATPP_ASSERT(sizeof(v_char8) == 1);
|
||||
OATPP_ASSERT(sizeof(v_int16) == 2);
|
||||
OATPP_ASSERT(sizeof(v_word16) == 2);
|
||||
OATPP_ASSERT(sizeof(v_int32) == 4);
|
||||
OATPP_ASSERT(sizeof(v_int64) == 8);
|
||||
OATPP_ASSERT(sizeof(v_word32) == 4);
|
||||
OATPP_ASSERT(sizeof(v_word64) == 8);
|
||||
OATPP_ASSERT(sizeof(v_float64) == 8);
|
||||
|
||||
v_int32 vInt32 = ~1;
|
||||
v_int64 vInt64 = ~1;
|
||||
v_word32 vWord32 = ~1;
|
||||
v_word64 vWord64 = ~1;
|
||||
|
||||
OATPP_ASSERT(vInt32 < 0);
|
||||
OATPP_ASSERT(vInt64 < 0);
|
||||
OATPP_ASSERT(vWord32 > 0);
|
||||
OATPP_ASSERT(vWord64 > 0);
|
||||
|
||||
}
|
||||
|
||||
void Environment::incObjects(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
m_objectsCount ++;
|
||||
m_objectsCreated ++;
|
||||
m_threadLocalObjectsCount ++;
|
||||
m_threadLocalObjectsCreated ++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Environment::decObjects(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
m_objectsCount --;
|
||||
m_threadLocalObjectsCount --;
|
||||
#endif
|
||||
}
|
||||
|
||||
v_counter Environment::getObjectsCount(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
return m_objectsCount;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
v_counter Environment::getObjectsCreated(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
return m_objectsCreated;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
v_counter Environment::getThreadLocalObjectsCount(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
return m_threadLocalObjectsCount;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
v_counter Environment::getThreadLocalObjectsCreated(){
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
return m_threadLocalObjectsCreated;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Environment::setLogger(Logger* logger){
|
||||
if(m_logger != nullptr){
|
||||
delete m_logger;
|
||||
}
|
||||
m_logger = logger;
|
||||
}
|
||||
|
||||
void Environment::log(v_int32 priority, const std::string& tag, const std::string& message) {
|
||||
if(m_logger != nullptr) {
|
||||
m_logger->log(priority, tag, message);
|
||||
}
|
||||
}
|
||||
|
||||
void Environment::logFormatted(v_int32 priority, const std::string& tag, const char* message, ...) {
|
||||
char buffer[1025];
|
||||
va_list args;
|
||||
va_start (args, message);
|
||||
vsnprintf(buffer, 1024, message, args);
|
||||
log(priority, tag, buffer);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Environment::registerComponent(const std::string& typeName, const std::string& componentName, void* component) {
|
||||
auto& bucket = m_components[typeName];
|
||||
auto it = bucket.find(componentName);
|
||||
if(it != bucket.end()){
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Component with given name already exists: name='" + componentName + "'");
|
||||
}
|
||||
bucket[componentName] = component;
|
||||
}
|
||||
|
||||
void Environment::unregisterComponent(const std::string& typeName, const std::string& componentName) {
|
||||
auto bucketIt = m_components.find(typeName);
|
||||
if(bucketIt == m_components.end() || bucketIt->second.size() == 0) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Component of given type does't exist: type='" + typeName + "'");
|
||||
}
|
||||
auto& bucket = bucketIt->second;
|
||||
auto componentIt = bucket.find(componentName);
|
||||
if(componentIt == bucket.end()) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Component with given name does't exist: name='" + componentName + "'");
|
||||
}
|
||||
bucket.erase(componentIt);
|
||||
if(bucket.size() == 0) {
|
||||
m_components.erase(bucketIt);
|
||||
}
|
||||
}
|
||||
|
||||
void* Environment::getComponent(const std::string& typeName) {
|
||||
auto bucketIt = m_components.find(typeName);
|
||||
if(bucketIt == m_components.end() || bucketIt->second.size() == 0) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Component of given type does't exist: type='" + typeName + "'");
|
||||
}
|
||||
auto bucket = bucketIt->second;
|
||||
if(bucket.size() > 1){
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Ambiguous component reference. Multiple components exist for a given type: type='" + typeName + "'");
|
||||
}
|
||||
return bucket.begin()->second;
|
||||
}
|
||||
|
||||
void* Environment::getComponent(const std::string& typeName, const std::string& componentName) {
|
||||
auto bucketIt = m_components.find(typeName);
|
||||
if(bucketIt == m_components.end() || bucketIt->second.size() == 0) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Component of given type does't exist: type='" + typeName + "'");
|
||||
}
|
||||
auto bucket = bucketIt->second;
|
||||
auto componentIt = bucket.find(componentName);
|
||||
if(componentIt == bucket.end()) {
|
||||
throw std::runtime_error("[oatpp::base::Environment]: Component with given name does't exist: name='" + componentName + "'");
|
||||
}
|
||||
return componentIt->second;
|
||||
}
|
||||
|
||||
}}
|
187
core/src/base/Environment.hpp
Normal file
187
core/src/base/Environment.hpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_base_Environment_hpp
|
||||
#define oatpp_base_Environment_hpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifndef OATPP_DISABLE_ASSERT
|
||||
|
||||
#define OATPP_ASSERT(EXP) \
|
||||
if(!(EXP)) { \
|
||||
OATPP_LOGE("ASSERT[FAILED]", #EXP); \
|
||||
throw std::runtime_error("ASSERT[FAILED]:" #EXP); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define OATPP_ASSERT(EXP)
|
||||
#endif
|
||||
|
||||
typedef unsigned char v_char8;
|
||||
typedef v_char8 *p_char8;
|
||||
|
||||
typedef long long v_int64;
|
||||
typedef v_int64 * p_int64;
|
||||
typedef unsigned long long v_word64;
|
||||
typedef v_word64 * p_word64;
|
||||
|
||||
typedef short int v_int16;
|
||||
typedef v_int64 * p_int16;
|
||||
|
||||
typedef unsigned short int v_word16;
|
||||
typedef v_word16 * p_word16;
|
||||
|
||||
typedef int v_int32;
|
||||
typedef v_int32 * p_int32;
|
||||
typedef unsigned int v_word32;
|
||||
typedef v_word32 * p_word32;
|
||||
|
||||
typedef double v_float64;
|
||||
typedef v_float64 * p_float64;
|
||||
|
||||
typedef float v_float32;
|
||||
typedef v_float32* p_float32;
|
||||
|
||||
typedef v_int64 v_timeMillis;
|
||||
|
||||
typedef std::atomic_int_fast64_t v_atomicCounter;
|
||||
typedef v_int64 v_counter;
|
||||
|
||||
const v_int32 MIN_INT_32 = -2147483648;
|
||||
const v_int32 MAX_INT_32 = 2147483647;
|
||||
|
||||
//const v_int64 MIN_INT_64 = -9223372036854775808;
|
||||
const v_int64 MAX_INT_64 = 9223372036854775807;
|
||||
const v_int64 MIN_INT_64 = - MAX_INT_64 - 1;
|
||||
|
||||
namespace oatpp { namespace base{
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
virtual ~Logger(){};
|
||||
virtual void log(v_int32 priority, const std::string& tag, const std::string& message) = 0;
|
||||
};
|
||||
|
||||
//#define OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
|
||||
class Environment{
|
||||
private:
|
||||
#ifndef OATPP_DISABLE_ENV_OBJECT_COUNTERS
|
||||
static v_atomicCounter m_objectsCount;
|
||||
static v_atomicCounter m_objectsCreated;
|
||||
static thread_local v_counter m_threadLocalObjectsCount;
|
||||
static thread_local v_counter m_threadLocalObjectsCreated;
|
||||
#endif
|
||||
private:
|
||||
static Logger* m_logger;
|
||||
static void checkTypes();
|
||||
private:
|
||||
static std::unordered_map<std::string, std::unordered_map<std::string, void*>> m_components;
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
class Component {
|
||||
private:
|
||||
std::string m_type;
|
||||
std::string m_name;
|
||||
T m_object;
|
||||
public:
|
||||
|
||||
Component(const std::string& name, const T& object)
|
||||
: m_type(typeid(T).name())
|
||||
, m_name(name)
|
||||
, m_object(object)
|
||||
{
|
||||
Environment::registerComponent(m_type, m_name, &m_object);
|
||||
}
|
||||
|
||||
Component(const T& object)
|
||||
: Component("NoName", object)
|
||||
{}
|
||||
|
||||
~Component() {
|
||||
Environment::unregisterComponent(m_type, m_name);
|
||||
}
|
||||
|
||||
T getObject() {
|
||||
return m_object;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
static void registerComponent(const std::string& typeName, const std::string& componentName, void* component);
|
||||
static void unregisterComponent(const std::string& typeName, const std::string& componentName);
|
||||
public:
|
||||
|
||||
static void init();
|
||||
static void destroy();
|
||||
|
||||
static void incObjects();
|
||||
static void decObjects();
|
||||
|
||||
static v_counter getObjectsCount();
|
||||
static v_counter getObjectsCreated();
|
||||
|
||||
static v_counter getThreadLocalObjectsCount();
|
||||
static v_counter getThreadLocalObjectsCreated();
|
||||
|
||||
static void setLogger(Logger* logger);
|
||||
|
||||
static void log(v_int32 priority, const std::string& tag, const std::string& message);
|
||||
static void logFormatted(v_int32 priority, const std::string& tag, const char* message, ...);
|
||||
|
||||
static void* getComponent(const std::string& typeName);
|
||||
static void* getComponent(const std::string& typeName, const std::string& componentName);
|
||||
|
||||
};
|
||||
|
||||
#ifndef OATPP_DISABLE_LOGV
|
||||
#define OATPP_LOGV(TAG, ...) oatpp::base::Environment::logFormatted(0, TAG, __VA_ARGS__);
|
||||
#else
|
||||
#define OATPP_LOGV(TAG, ...)
|
||||
#endif
|
||||
|
||||
#ifndef OATPP_DISABLE_LOGD
|
||||
#define OATPP_LOGD(TAG, ...) oatpp::base::Environment::logFormatted(1, TAG, __VA_ARGS__);
|
||||
#else
|
||||
#define OATPP_LOGD(TAG, ...)
|
||||
#endif
|
||||
|
||||
#ifndef OATPP_DISABLE_LOGE
|
||||
#define OATPP_LOGE(TAG, ...) oatpp::base::Environment::logFormatted(2, TAG, __VA_ARGS__);
|
||||
#else
|
||||
#define OATPP_LOGE(TAG, ...)
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif /* oatpp_base_Environment_hpp */
|
25
core/src/base/SharedWrapper.cpp
Normal file
25
core/src/base/SharedWrapper.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "SharedWrapper.hpp"
|
105
core/src/base/SharedWrapper.hpp
Normal file
105
core/src/base/SharedWrapper.hpp
Normal file
@ -0,0 +1,105 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_base_SharedWrapper
|
||||
#define oatpp_base_SharedWrapper
|
||||
|
||||
#include "Controllable.hpp"
|
||||
|
||||
namespace oatpp { namespace base {
|
||||
|
||||
template<class T>
|
||||
class SharedWrapper {
|
||||
protected:
|
||||
std::shared_ptr<T> m_ptr;
|
||||
public:
|
||||
|
||||
SharedWrapper() {}
|
||||
|
||||
SharedWrapper(const std::shared_ptr<T>& ptr)
|
||||
: m_ptr(ptr)
|
||||
{}
|
||||
|
||||
SharedWrapper(std::shared_ptr<T>&& ptr)
|
||||
: m_ptr(std::move(ptr))
|
||||
{}
|
||||
|
||||
SharedWrapper(const SharedWrapper& other)
|
||||
: m_ptr(other.m_ptr)
|
||||
{}
|
||||
|
||||
SharedWrapper(SharedWrapper&& other)
|
||||
: m_ptr(std::move(other.m_ptr))
|
||||
{}
|
||||
|
||||
SharedWrapper& operator = (const SharedWrapper& other){
|
||||
m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedWrapper& operator = (SharedWrapper&& other){
|
||||
m_ptr = std::move(other.m_ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T* operator->() const {
|
||||
return m_ptr.operator->();
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return m_ptr.get();
|
||||
}
|
||||
|
||||
std::shared_ptr<T> getPtr() const {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
static const SharedWrapper& empty(){
|
||||
static SharedWrapper empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
inline bool operator == (const SharedWrapper& other){
|
||||
return m_ptr.get() == other.m_ptr.get();
|
||||
}
|
||||
|
||||
inline bool operator != (const SharedWrapper& other){
|
||||
return m_ptr.get() != other.m_ptr.get();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class T, class F>
|
||||
inline SharedWrapper<T> static_wrapper_cast(const F& from){
|
||||
return SharedWrapper<T>(std::static_pointer_cast<T>(from.getPtr()));
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif /* oatpp_base_SharedWrapper */
|
293
core/src/base/String.cpp
Normal file
293
core/src/base/String.cpp
Normal file
@ -0,0 +1,293 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "String.hpp"
|
||||
|
||||
namespace oatpp { namespace base {
|
||||
|
||||
void String::setAndCopy(const void* data, const void* originData, v_int32 size){
|
||||
m_data = (p_char8) data;
|
||||
m_size = size;
|
||||
//m_hasOwnData = false;
|
||||
if(originData != nullptr) {
|
||||
std::memcpy(m_data, originData, size);
|
||||
}
|
||||
m_data[size] = 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::allocShared(const void* data, v_int32 size, bool copyAsOwnData) {
|
||||
if(copyAsOwnData) {
|
||||
memory::AllocationExtras extras(size + 1);
|
||||
const auto& ptr = memory::allocateSharedWithExtras<String>(extras);
|
||||
ptr->setAndCopy(extras.extraPtr, data, size);
|
||||
return ptr;
|
||||
}
|
||||
return std::make_shared<String>(data, size, copyAsOwnData);
|
||||
}
|
||||
|
||||
p_char8 String::allocString(const void* originData, v_int32 size, bool copyAsOwnData) {
|
||||
if(copyAsOwnData) {
|
||||
p_char8 data = new v_char8[size + 1];
|
||||
data[size] = 0;
|
||||
if(originData != nullptr) {
|
||||
std::memcpy(data, originData, size);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
return (p_char8) originData;
|
||||
}
|
||||
|
||||
String::~String() {
|
||||
if(m_hasOwnData) {
|
||||
delete [] m_data;
|
||||
}
|
||||
m_data = nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::createShared(const void* data, v_int32 size, bool copyAsOwnData) {
|
||||
return allocShared(data, size, copyAsOwnData);
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::createShared(const char* data, bool copyAsOwnData) {
|
||||
return allocShared(data, (v_int32) std::strlen(data), copyAsOwnData);
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::createShared(String* other, bool copyAsOwnData) {
|
||||
return allocShared(other->getData(), other->getSize(), copyAsOwnData);
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::createShared(v_int32 size) {
|
||||
return allocShared(nullptr, size, true);
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::createSharedConcatenated(const void* data1, v_int32 size1, const void* data2, v_int32 size2) {
|
||||
const auto& ptr = allocShared(nullptr, size1 + size2, true);
|
||||
std::memcpy(ptr->m_data, data1, size1);
|
||||
std::memcpy(ptr->m_data + size1, data2, size2);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
p_char8 String::getData() const {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
v_int32 String::getSize() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
const char* String::c_str() const {
|
||||
return (const char*) m_data;
|
||||
}
|
||||
|
||||
bool String::hasOwnData() const {
|
||||
return m_hasOwnData;
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::toLowerCase() const {
|
||||
return createShared(allocateAndLowerCase(m_data, m_size), m_size, true);
|
||||
}
|
||||
|
||||
std::shared_ptr<String> String::toUpperCase() const {
|
||||
return createShared(allocateAndUpperCase(m_data, m_size), m_size, true);
|
||||
}
|
||||
|
||||
bool String::equals(const void* data, v_int32 size) const {
|
||||
if(m_size == size) {
|
||||
return equals(m_data, data, size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool String::equals(const char* data) const {
|
||||
if(m_size == (v_int32) std::strlen(data)) {
|
||||
return equals(m_data, data, m_size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool String::equals(String* other) const {
|
||||
return equals((String*) this, other);
|
||||
}
|
||||
|
||||
bool String::equals(const String::SharedWrapper& other) const {
|
||||
return equals((String*) this, other.get());
|
||||
}
|
||||
|
||||
bool String::equals(const std::shared_ptr<String>& other) const {
|
||||
return equals((String*) this, other.get());
|
||||
}
|
||||
|
||||
bool String::startsWith(const void* data, v_int32 size) const {
|
||||
if(m_size >= size) {
|
||||
return equals(m_data, data, size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool String::startsWith(const char* data) const {
|
||||
v_int32 length = (v_int32) std::strlen(data);
|
||||
if(m_size >= length) {
|
||||
return equals(m_data, data, length);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool String::startsWith(String* data) const {
|
||||
if(m_size >= data->m_size) {
|
||||
return equals(m_data, data, data->m_size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
v_int32 String::compare(const void* data1, const void* data2, v_int32 size) {
|
||||
return std::memcmp(data1, data2, size);
|
||||
}
|
||||
|
||||
v_int32 String::compare(String* str1, String* str2) {
|
||||
if(str1 == str2) {
|
||||
return 0;
|
||||
}
|
||||
if(str1->m_size < str2->m_size) {
|
||||
return compare(str1->m_data, str2->m_data, str1->m_size);
|
||||
} else {
|
||||
return compare(str1->m_data, str2->m_data, str2->m_size);
|
||||
}
|
||||
}
|
||||
|
||||
bool String::equals(const void* data1, const void* data2, v_int32 size) {
|
||||
return (data1 == data2) || (std::memcmp(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool String::equals(const char* data1, const char* data2) {
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr && data2 == nullptr) return false;
|
||||
v_int32 size = (v_int32) std::strlen(data1);
|
||||
return (size == (v_int32) std::strlen(data2) && std::memcmp(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool String::equals(String* str1, String* 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)
|
||||
);
|
||||
}
|
||||
|
||||
bool String::equalsCI(const void* data1, const void* data2, v_int32 size) {
|
||||
for(v_int32 i = 0; i < size; i++) {
|
||||
v_char8 a = ((p_char8) data1) [i];
|
||||
v_char8 b = ((p_char8) data2) [i];
|
||||
if(a >= 'A' && a <= 'Z') a |= 32;
|
||||
if(b >= 'A' && b <= 'Z') b |= 32;
|
||||
if(a != b) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool String::equalsCI(const char* data1, const char* data2) {
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr && data2 == nullptr) return false;
|
||||
v_int32 size = (v_int32) std::strlen(data1);
|
||||
return (size == (v_int32) std::strlen(data2) && equalsCI(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool String::equalsCI(String* str1, String* 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))
|
||||
);
|
||||
}
|
||||
|
||||
bool String::equalsCI_FAST(const void* data1, const void* data2, v_int32 size) {
|
||||
for(v_int32 i = 0; i < size; i++) {
|
||||
if((((p_char8) data1) [i] | 32) != (((p_char8) data2) [i] | 32)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool String::equalsCI_FAST(const char* data1, const char* data2) {
|
||||
if(data1 == data2) return true;
|
||||
if(data1 == nullptr && data2 == nullptr) return false;
|
||||
v_int32 size = (v_int32) std::strlen(data1);
|
||||
return (size == (v_int32) std::strlen(data2) && equalsCI_FAST(data1, data2, size) == 0);
|
||||
}
|
||||
|
||||
bool String::equalsCI_FAST(String* str1, String* 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))
|
||||
);
|
||||
}
|
||||
|
||||
bool String::equalsCI_FAST(const String::SharedWrapper& str1, const char* str2) {
|
||||
v_int32 len = (v_int32) std::strlen(str2);
|
||||
return (str1->getSize() == len && equalsCI_FAST(str1->m_data, str2, str1->m_size));
|
||||
}
|
||||
|
||||
p_char8 String::allocateAndLowerCase(const void* originData, v_int32 size) {
|
||||
p_char8 result = new v_char8[size + 1];
|
||||
for(v_int32 i = 0; i < size; i++) {
|
||||
v_char8 a = ((p_char8)originData)[i];
|
||||
if(a >= 'A' && a <= 'Z') a |= 32;
|
||||
result[i] = a;
|
||||
}
|
||||
result[size] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
p_char8 String::allocateAndUpperCase(const void* originData, v_int32 size) {
|
||||
p_char8 result = new v_char8[size + 1];
|
||||
for(v_int32 i = 0; i < size; i++) {
|
||||
v_char8 a = ((p_char8)originData)[i];
|
||||
if(a >= 'a' && a <= 'z') a &= 223;
|
||||
result[i] = a;
|
||||
}
|
||||
result[size] = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Operator
|
||||
|
||||
oatpp::base::SharedWrapper<String> operator + (const char* a, const oatpp::base::SharedWrapper<String>& b){
|
||||
return String::createSharedConcatenated(a, (v_int32) std::strlen(a), b->getData(), b->getSize());
|
||||
}
|
||||
|
||||
oatpp::base::SharedWrapper<String> operator + (const oatpp::base::SharedWrapper<String>& b, const char* a){
|
||||
return String::createSharedConcatenated(b->getData(), b->getSize(), a, (v_int32) std::strlen(a));
|
||||
}
|
||||
|
||||
std::shared_ptr<String> operator + (const char* a, const std::shared_ptr<String>& b){
|
||||
return String::createSharedConcatenated(a, (v_int32) std::strlen(a), b->getData(), b->getSize());
|
||||
}
|
||||
|
||||
std::shared_ptr<String> operator + (const std::shared_ptr<String>& b, const char* a){
|
||||
return String::createSharedConcatenated(b->getData(), b->getSize(), a, (v_int32) std::strlen(a));
|
||||
}
|
||||
|
||||
}}
|
212
core/src/base/String.hpp
Normal file
212
core/src/base/String.hpp
Normal file
@ -0,0 +1,212 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_base_String_hpp
|
||||
#define oatpp_base_String_hpp
|
||||
|
||||
#include "memory/ObjectPool.hpp"
|
||||
#include "./Controllable.hpp"
|
||||
#include "./SharedWrapper.hpp"
|
||||
|
||||
#include <cstring> // c
|
||||
|
||||
namespace oatpp { namespace base {
|
||||
|
||||
class String : public oatpp::base::Controllable {
|
||||
public:
|
||||
|
||||
class SharedWrapper : public oatpp::base::SharedWrapper<String> {
|
||||
public:
|
||||
|
||||
SharedWrapper() {}
|
||||
|
||||
SharedWrapper(const std::shared_ptr<String>& ptr)
|
||||
: oatpp::base::SharedWrapper<String>(ptr)
|
||||
{}
|
||||
|
||||
SharedWrapper(std::shared_ptr<String>&& ptr)
|
||||
: oatpp::base::SharedWrapper<String>(std::move(ptr))
|
||||
{}
|
||||
|
||||
SharedWrapper(const char* str)
|
||||
: oatpp::base::SharedWrapper<String>(createFromCString(str))
|
||||
{}
|
||||
|
||||
SharedWrapper(const oatpp::base::SharedWrapper<String>& other)
|
||||
: oatpp::base::SharedWrapper<String>(other)
|
||||
{}
|
||||
|
||||
SharedWrapper(oatpp::base::SharedWrapper<String>&& other)
|
||||
: oatpp::base::SharedWrapper<String>(std::move(other))
|
||||
{}
|
||||
|
||||
SharedWrapper& operator = (const char* str) {
|
||||
m_ptr = String::createFromCString(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedWrapper& operator = (const oatpp::base::SharedWrapper<String>& other){
|
||||
oatpp::base::SharedWrapper<String>::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedWrapper& operator = (oatpp::base::SharedWrapper<String>&& other){
|
||||
oatpp::base::SharedWrapper<String>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedWrapper operator + (const char* str) const{
|
||||
return String::createSharedConcatenated(m_ptr.get()->m_data, m_ptr.get()->m_size, str, (v_int32) std::strlen(str));
|
||||
}
|
||||
|
||||
SharedWrapper operator + (const oatpp::base::SharedWrapper<String>& other) const{
|
||||
return String::createSharedConcatenated(m_ptr.get()->m_data, m_ptr.get()->m_size, other.get()->m_data, other.get()->m_size);
|
||||
}
|
||||
|
||||
static const SharedWrapper& empty(){
|
||||
static SharedWrapper empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
OBJECT_POOL_THREAD_LOCAL(String_Pool, String, 32)
|
||||
private:
|
||||
p_char8 m_data;
|
||||
v_int32 m_size;
|
||||
bool m_hasOwnData;
|
||||
private:
|
||||
|
||||
void setAndCopy(const void* data, const void* originData, v_int32 size);
|
||||
static std::shared_ptr<String> allocShared(const void* data, v_int32 size, bool copyAsOwnData);
|
||||
|
||||
/**
|
||||
* Allocate memory for string or use originData
|
||||
* if copyAsOwnData == false return originData
|
||||
*/
|
||||
static p_char8 allocString(const void* originData, v_int32 size, bool copyAsOwnData);
|
||||
|
||||
public:
|
||||
String()
|
||||
: m_data((p_char8)"[<nullptr>]")
|
||||
, m_size(11)
|
||||
, m_hasOwnData(false)
|
||||
{}
|
||||
|
||||
String(const void* data, v_int32 size, bool copyAsOwnData)
|
||||
: m_data(allocString(data, size, copyAsOwnData))
|
||||
, m_size(size)
|
||||
, m_hasOwnData(copyAsOwnData)
|
||||
{}
|
||||
public:
|
||||
|
||||
virtual ~String();
|
||||
|
||||
static std::shared_ptr<String> createShared(v_int32 size);
|
||||
static std::shared_ptr<String> createShared(const void* data, v_int32 size, bool copyAsOwnData = true);
|
||||
static std::shared_ptr<String> createShared(const char* data, bool copyAsOwnData = true);
|
||||
static std::shared_ptr<String> createShared(String* other, bool copyAsOwnData = true);
|
||||
|
||||
static std::shared_ptr<String> createSharedConcatenated(const void* data1, v_int32 size1, const void* data2, v_int32 size2);
|
||||
|
||||
static std::shared_ptr<String> createFromCString(const char* data, bool copyAsOwnData = true) {
|
||||
if(data != nullptr) {
|
||||
return allocShared(data, (v_int32) std::strlen(data), copyAsOwnData);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
p_char8 getData() const;
|
||||
v_int32 getSize() const;
|
||||
|
||||
const char* c_str() const;
|
||||
|
||||
bool hasOwnData() const;
|
||||
|
||||
/**
|
||||
* (correct for ACII only)
|
||||
*/
|
||||
std::shared_ptr<String> toLowerCase() const;
|
||||
|
||||
/**
|
||||
* (correct for ACII only)
|
||||
*/
|
||||
std::shared_ptr<String> toUpperCase() const;
|
||||
|
||||
bool equals(const void* data, v_int32 size) const;
|
||||
bool equals(const char* data) const;
|
||||
bool equals(String* other) const;
|
||||
bool equals(const String::SharedWrapper& other) const;
|
||||
bool equals(const std::shared_ptr<String>& other) const;
|
||||
|
||||
bool startsWith(const void* data, v_int32 size) const;
|
||||
bool startsWith(const char* data) const;
|
||||
bool startsWith(String* data) const;
|
||||
|
||||
public:
|
||||
|
||||
static v_int32 compare(const void* data1, const void* data2, v_int32 size);
|
||||
static v_int32 compare(String* str1, String* str2);
|
||||
|
||||
static bool equals(const void* data1, const void* data2, v_int32 size);
|
||||
static bool equals(const char* data1, const char* data2);
|
||||
static bool equals(String* str1, String* str2);
|
||||
|
||||
// Case Insensitive (correct for ASCII only)
|
||||
|
||||
static bool equalsCI(const void* data1, const void* data2, v_int32 size);
|
||||
static bool equalsCI(const char* data1, const char* data2);
|
||||
static bool equalsCI(String* str1, String* str2);
|
||||
|
||||
// Case Insensitive Fast (ASCII only, correct compare if one of strings contains letters only)
|
||||
|
||||
static bool equalsCI_FAST(const void* data1, const void* data2, v_int32 size);
|
||||
static bool equalsCI_FAST(const char* data1, const char* data2);
|
||||
static bool equalsCI_FAST(String* str1, String* str2);
|
||||
static bool equalsCI_FAST(const String::SharedWrapper& str1, const char* str2);
|
||||
|
||||
/**
|
||||
* allocate memory of size + 1 (in bytes) and fill it with originData lowercased (correct for ACII only)
|
||||
* additional char allocated for '\0'
|
||||
*/
|
||||
static p_char8 allocateAndLowerCase(const void* originData, v_int32 size);
|
||||
|
||||
/**
|
||||
* allocate memory of size + 1 (in bytes) and fill it with originData UPPERCASED (correct for ACII only)
|
||||
* additional char allocated for '\0'
|
||||
*/
|
||||
static p_char8 allocateAndUpperCase(const void* originData, v_int32 size);
|
||||
|
||||
};
|
||||
|
||||
oatpp::base::SharedWrapper<String> operator + (const char* a, const oatpp::base::SharedWrapper<String>& b);
|
||||
oatpp::base::SharedWrapper<String> operator + (const oatpp::base::SharedWrapper<String>& b, const char* a);
|
||||
|
||||
std::shared_ptr<String> operator + (const char* a, const std::shared_ptr<String>& b);
|
||||
std::shared_ptr<String> operator + (const std::shared_ptr<String>& b, const char* a);
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_base_String_hpp */
|
9
core/src/base/memory/Allocator.cpp
Normal file
9
core/src/base/memory/Allocator.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
//
|
||||
// Allocator.cpp
|
||||
// oatpp-web-starter
|
||||
//
|
||||
// Created by Leonid on 3/12/18.
|
||||
// Copyright © 2018 lganzzzo. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Allocator.hpp"
|
166
core/src/base/memory/Allocator.hpp
Normal file
166
core/src/base/memory/Allocator.hpp
Normal file
@ -0,0 +1,166 @@
|
||||
//
|
||||
// Allocator.hpp
|
||||
// oatpp-web-starter
|
||||
//
|
||||
// Created by Leonid on 3/12/18.
|
||||
// Copyright © 2018 lganzzzo. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef oatpp_base_memory_Allocator_hpp
|
||||
#define oatpp_base_memory_Allocator_hpp
|
||||
|
||||
#include "./MemoryPool.hpp"
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
class AllocatorPoolInfo {
|
||||
public:
|
||||
AllocatorPoolInfo(const char* pPoolName, v_int32 pPoolChunkSize)
|
||||
: poolName(pPoolName)
|
||||
, poolChunkSize(pPoolChunkSize)
|
||||
{}
|
||||
const char* const poolName;
|
||||
const v_int32 poolChunkSize;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class PoolSharedObjectAllocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
public:
|
||||
const AllocatorPoolInfo& m_poolInfo;
|
||||
public:
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getPool(const AllocatorPoolInfo& info){
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool pool(info.poolName, sizeof(T), info.poolChunkSize);
|
||||
return pool;
|
||||
}
|
||||
public:
|
||||
PoolSharedObjectAllocator(const AllocatorPoolInfo& info)
|
||||
: m_poolInfo(info)
|
||||
{};
|
||||
|
||||
template<typename U>
|
||||
PoolSharedObjectAllocator(const PoolSharedObjectAllocator<U>& other)
|
||||
: m_poolInfo(other.m_poolInfo)
|
||||
{};
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
return static_cast<T*>(getPool(m_poolInfo).obtain());
|
||||
}
|
||||
|
||||
void deallocate(T* ptr, size_t n) {
|
||||
oatpp::base::memory::MemoryPool::free(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator == (const PoolSharedObjectAllocator<T>&, const PoolSharedObjectAllocator<U>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator != (const PoolSharedObjectAllocator<T>& a, const PoolSharedObjectAllocator<U>& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class ThreadLocalPoolSharedObjectAllocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
public:
|
||||
const AllocatorPoolInfo& m_poolInfo;
|
||||
public:
|
||||
static oatpp::base::memory::MemoryPool& getPool(const AllocatorPoolInfo& info){
|
||||
static thread_local oatpp::base::memory::MemoryPool pool(info.poolName, sizeof(T), info.poolChunkSize);
|
||||
return pool;
|
||||
}
|
||||
public:
|
||||
ThreadLocalPoolSharedObjectAllocator(const ThreadLocalPoolSharedObjectAllocator& info)
|
||||
: m_poolInfo(info)
|
||||
{};
|
||||
|
||||
template<typename U>
|
||||
ThreadLocalPoolSharedObjectAllocator(const ThreadLocalPoolSharedObjectAllocator<U>& other)
|
||||
: m_poolInfo(other.m_poolInfo)
|
||||
{};
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
return static_cast<T*>(getPool(m_poolInfo).obtain());
|
||||
}
|
||||
|
||||
void deallocate(T* ptr, size_t n) {
|
||||
oatpp::base::memory::MemoryPool::free(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator == (const ThreadLocalPoolSharedObjectAllocator<T>&, const ThreadLocalPoolSharedObjectAllocator<U>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator != (const ThreadLocalPoolSharedObjectAllocator<T>& a, const ThreadLocalPoolSharedObjectAllocator<U>& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
class AllocationExtras {
|
||||
public:
|
||||
AllocationExtras(v_int32 pExtraWanted)
|
||||
: extraWanted(pExtraWanted)
|
||||
{}
|
||||
const v_int32 extraWanted;
|
||||
void* extraPtr;
|
||||
v_int32 baseSize;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class SharedObjectAllocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
public:
|
||||
AllocationExtras& m_info;
|
||||
public:
|
||||
|
||||
SharedObjectAllocator(AllocationExtras& info)
|
||||
: m_info(info)
|
||||
{};
|
||||
|
||||
template<typename U>
|
||||
SharedObjectAllocator(const SharedObjectAllocator<U>& other)
|
||||
: m_info(other.m_info)
|
||||
{};
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
void* mem = ::operator new(sizeof(T) + m_info.extraWanted);
|
||||
m_info.baseSize = sizeof(T);
|
||||
m_info.extraPtr = &((p_char8) mem)[sizeof(T)];
|
||||
return static_cast<T*>(mem);
|
||||
}
|
||||
|
||||
void deallocate(T* ptr, size_t n) {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator == (const SharedObjectAllocator<T>&, const SharedObjectAllocator<U>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline bool operator != (const SharedObjectAllocator<T>& a, const SharedObjectAllocator<U>& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
static std::shared_ptr<T> allocateSharedWithExtras(AllocationExtras& extras, Args... args){
|
||||
SharedObjectAllocator<T> allocator(extras);
|
||||
return std::shared_ptr<T>::allocate_shared(allocator, args...);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_base_memory_Allocator_hpp */
|
56
core/src/base/memory/MemoryPool.cpp
Normal file
56
core/src/base/memory/MemoryPool.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "MemoryPool.hpp"
|
||||
#include "../../utils/ConversionUtils.hpp"
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
oatpp::concurrency::SpinLock::Atom MemoryPool::POOLS_ATOM(false);
|
||||
std::unordered_map<v_int64, MemoryPool*> MemoryPool::POOLS;
|
||||
std::atomic<v_int64> MemoryPool::poolIdCounter(0);
|
||||
|
||||
ThreadDistributedMemoryPool::ThreadDistributedMemoryPool(const std::string& name, v_int32 entrySize, v_int32 chunkSize)
|
||||
: m_shardsCount(10)
|
||||
, m_shards(new MemoryPool*[m_shardsCount])
|
||||
{
|
||||
for(v_int32 i = 0; i < m_shardsCount; i++){
|
||||
m_shards[i] = new MemoryPool(name + "_" + oatpp::utils::conversion::int32ToStdStr(i), entrySize, chunkSize);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadDistributedMemoryPool::~ThreadDistributedMemoryPool(){
|
||||
for(v_int32 i = 0; i < m_shardsCount; i++){
|
||||
delete m_shards[i];
|
||||
}
|
||||
delete [] m_shards;
|
||||
}
|
||||
|
||||
void* ThreadDistributedMemoryPool::obtain() {
|
||||
static std::atomic<v_word16> base(0);
|
||||
static thread_local v_int16 index = (++base) % m_shardsCount;
|
||||
return m_shards[index]->obtain();
|
||||
}
|
||||
|
||||
}}}
|
186
core/src/base/memory/MemoryPool.hpp
Normal file
186
core/src/base/memory/MemoryPool.hpp
Normal file
@ -0,0 +1,186 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_base_memory_MemoryPool_hpp
|
||||
#define oatpp_base_memory_MemoryPool_hpp
|
||||
|
||||
#include "../../concurrency/SpinLock.hpp"
|
||||
#include "../Environment.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
//#define OATPP_DISABLE_POOL_ALLOCATIONS
|
||||
|
||||
//#ifndef OATPP_MEMORY_POOL_SHARDING
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
class MemoryPool {
|
||||
public:
|
||||
static oatpp::concurrency::SpinLock::Atom POOLS_ATOM;
|
||||
static std::unordered_map<v_int64, MemoryPool*> POOLS;
|
||||
private:
|
||||
static std::atomic<v_int64> poolIdCounter;
|
||||
private:
|
||||
|
||||
class EntryHeader {
|
||||
public:
|
||||
|
||||
EntryHeader(MemoryPool* pPool, v_int64 pPoolId, EntryHeader* pNext)
|
||||
: pool(pPool)
|
||||
, poolId(pPoolId)
|
||||
, next(pNext)
|
||||
{}
|
||||
|
||||
MemoryPool* pool;
|
||||
v_int64 poolId;
|
||||
EntryHeader* next;
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void allocChunk() {
|
||||
v_int32 entryBlockSize = sizeof(EntryHeader) + m_entrySize;
|
||||
v_int32 chunkMemSize = entryBlockSize * m_chunkSize;
|
||||
p_char8 mem = new v_char8[chunkMemSize];
|
||||
m_chunks.push_back(mem);
|
||||
for(v_int32 i = 0; i < m_chunkSize; i++){
|
||||
EntryHeader* entry = new (mem + i * entryBlockSize) EntryHeader(this, m_id, m_rootEntry);
|
||||
m_rootEntry = entry;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
v_int32 m_entrySize;
|
||||
v_int32 m_chunkSize;
|
||||
v_int64 m_id;
|
||||
std::list<p_char8> m_chunks;
|
||||
EntryHeader* m_rootEntry;
|
||||
oatpp::concurrency::SpinLock::Atom m_atom;
|
||||
v_int32 m_objectsCount;
|
||||
public:
|
||||
|
||||
MemoryPool(const std::string& name, v_int32 entrySize, v_int32 chunkSize)
|
||||
: m_name(name)
|
||||
, m_entrySize(entrySize)
|
||||
, m_chunkSize(chunkSize)
|
||||
, m_id(++poolIdCounter)
|
||||
, m_rootEntry(nullptr)
|
||||
, m_atom(false)
|
||||
, m_objectsCount(0)
|
||||
{
|
||||
allocChunk();
|
||||
oatpp::concurrency::SpinLock lock(POOLS_ATOM);
|
||||
POOLS[m_id] = this;
|
||||
}
|
||||
|
||||
virtual ~MemoryPool() {
|
||||
auto it = m_chunks.begin();
|
||||
while (it != m_chunks.end()) {
|
||||
p_char8 chunk = *it;
|
||||
delete [] chunk;
|
||||
it++;
|
||||
}
|
||||
oatpp::concurrency::SpinLock lock(POOLS_ATOM);
|
||||
POOLS.erase(m_id);
|
||||
}
|
||||
|
||||
void* obtain() {
|
||||
#ifdef OATPP_DISABLE_POOL_ALLOCATIONS
|
||||
return new v_char8[m_entrySize];
|
||||
#else
|
||||
oatpp::concurrency::SpinLock lock(m_atom);
|
||||
if(m_rootEntry != nullptr) {
|
||||
auto entry = m_rootEntry;
|
||||
m_rootEntry = m_rootEntry->next;
|
||||
++ m_objectsCount;
|
||||
return ((p_char8) entry) + sizeof(EntryHeader);
|
||||
} else {
|
||||
allocChunk();
|
||||
if(m_rootEntry == nullptr) {
|
||||
throw std::runtime_error("oatpp::base::memory::MemoryPool: Unable to allocate entry");
|
||||
}
|
||||
auto entry = m_rootEntry;
|
||||
m_rootEntry = m_rootEntry->next;
|
||||
++ m_objectsCount;
|
||||
return ((p_char8) entry) + sizeof(EntryHeader);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void freeByEntryHeader(EntryHeader* entry) {
|
||||
if(entry->poolId == m_id) {
|
||||
oatpp::concurrency::SpinLock lock(m_atom);
|
||||
entry->next = m_rootEntry;
|
||||
m_rootEntry = entry;
|
||||
-- m_objectsCount;
|
||||
} else {
|
||||
throw std::runtime_error("oatpp::base::memory::MemoryPool: Invalid EntryHeader");
|
||||
}
|
||||
}
|
||||
|
||||
static void free(void* entry) {
|
||||
#ifdef OATPP_DISABLE_POOL_ALLOCATIONS
|
||||
delete [] ((p_char8) entry);
|
||||
#else
|
||||
EntryHeader* header = (EntryHeader*)(((p_char8) entry) - sizeof (EntryHeader));
|
||||
header->pool->freeByEntryHeader(header);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string getName(){
|
||||
return m_name;
|
||||
}
|
||||
|
||||
v_int32 getEntrySize(){
|
||||
return m_entrySize;
|
||||
}
|
||||
|
||||
v_int64 getSize(){
|
||||
return m_chunks.size() * m_chunkSize;
|
||||
}
|
||||
|
||||
v_int32 getObjectsCount(){
|
||||
return m_objectsCount;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ThreadDistributedMemoryPool {
|
||||
private:
|
||||
v_int32 m_shardsCount;
|
||||
MemoryPool** m_shards;
|
||||
public:
|
||||
ThreadDistributedMemoryPool(const std::string& name, v_int32 entrySize, v_int32 chunkSize);
|
||||
virtual ~ThreadDistributedMemoryPool();
|
||||
void* obtain();
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_base_memory_MemoryPool_hpp */
|
25
core/src/base/memory/ObjectPool.cpp
Normal file
25
core/src/base/memory/ObjectPool.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ObjectPool.hpp"
|
156
core/src/base/memory/ObjectPool.hpp
Normal file
156
core/src/base/memory/ObjectPool.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_base_memory_ObjectPool_hpp
|
||||
#define oatpp_base_memory_ObjectPool_hpp
|
||||
|
||||
#include "./Allocator.hpp"
|
||||
#include "./MemoryPool.hpp"
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
#define SHARED_OBJECT_POOL(NAME, TYPE, CHUNK_SIZE) \
|
||||
class NAME { \
|
||||
public: \
|
||||
typedef TYPE ObjectType; \
|
||||
typedef oatpp::base::memory::PoolSharedObjectAllocator<TYPE> Allocator; \
|
||||
public: \
|
||||
\
|
||||
static const oatpp::base::memory::AllocatorPoolInfo& getPoolInfo(){ \
|
||||
static oatpp::base::memory::AllocatorPoolInfo info(#NAME"<"#TYPE">", CHUNK_SIZE); \
|
||||
return info; \
|
||||
} \
|
||||
\
|
||||
static Allocator& getAllocator (){ \
|
||||
static Allocator allocator(getPoolInfo()); \
|
||||
return allocator; \
|
||||
} \
|
||||
\
|
||||
template<typename ... Args> \
|
||||
static std::shared_ptr<TYPE> allocateShared(Args... args){ \
|
||||
return std::shared_ptr<TYPE>::allocate_shared(getAllocator(), args...); \
|
||||
} \
|
||||
\
|
||||
};
|
||||
|
||||
|
||||
#define SHARED_OBJECT_POOL_THREAD_LOCAL(NAME, TYPE, CHUNK_SIZE) \
|
||||
class NAME { \
|
||||
public: \
|
||||
typedef TYPE ObjectType; \
|
||||
typedef oatpp::base::memory::ThreadLocalPoolSharedObjectAllocator<TYPE> Allocator; \
|
||||
public: \
|
||||
\
|
||||
static const oatpp::base::memory::AllocatorPoolInfo& getPoolInfo(){ \
|
||||
static oatpp::base::memory::AllocatorPoolInfo info(#NAME"<"#TYPE">", CHUNK_SIZE); \
|
||||
return info; \
|
||||
} \
|
||||
\
|
||||
static Allocator& getAllocator (){ \
|
||||
static Allocator allocator(getPoolInfo()); \
|
||||
return allocator; \
|
||||
} \
|
||||
\
|
||||
template<typename ... Args> \
|
||||
static std::shared_ptr<TYPE> allocateShared(Args... args){ \
|
||||
return std::shared_ptr<TYPE>::allocate_shared(getAllocator(), args...); \
|
||||
} \
|
||||
\
|
||||
};
|
||||
|
||||
#define OBJECT_POOL(POOL_NAME, TYPE, CHUNK_SIZE) \
|
||||
class POOL_NAME { \
|
||||
public: \
|
||||
\
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getPool(){ \
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool pool(#POOL_NAME"<"#TYPE">", sizeof(TYPE), CHUNK_SIZE); \
|
||||
return pool; \
|
||||
} \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
static void* operator new(std::size_t sz) { \
|
||||
if(sz != sizeof(TYPE)){ \
|
||||
throw std::runtime_error("wrong object size"); \
|
||||
} \
|
||||
static auto& pool = POOL_NAME::getPool(); \
|
||||
return pool.obtain(); \
|
||||
} \
|
||||
\
|
||||
static void operator delete(void* ptr, std::size_t sz) { \
|
||||
if(sz != sizeof(TYPE)){ \
|
||||
throw std::runtime_error("wrong object size"); \
|
||||
} \
|
||||
oatpp::base::memory::MemoryPool::free(ptr); \
|
||||
} \
|
||||
\
|
||||
static void* operator new(std::size_t sz, void* entry) { \
|
||||
if(sz != sizeof(TYPE)){ \
|
||||
throw std::runtime_error("wrong object size"); \
|
||||
} \
|
||||
return entry; \
|
||||
} \
|
||||
\
|
||||
static void operator delete(void* ptr, void* entry) { \
|
||||
}
|
||||
|
||||
#define OBJECT_POOL_THREAD_LOCAL(POOL_NAME, TYPE, CHUNK_SIZE) \
|
||||
class POOL_NAME { \
|
||||
public: \
|
||||
\
|
||||
static oatpp::base::memory::MemoryPool& getPool(){ \
|
||||
static thread_local oatpp::base::memory::MemoryPool pool(#POOL_NAME"<"#TYPE">", sizeof(TYPE), CHUNK_SIZE); \
|
||||
return pool; \
|
||||
} \
|
||||
\
|
||||
}; \
|
||||
\
|
||||
static void* operator new(std::size_t sz) { \
|
||||
if(sz != sizeof(TYPE)){ \
|
||||
throw std::runtime_error("wrong object size"); \
|
||||
} \
|
||||
static thread_local auto& pool = POOL_NAME::getPool(); \
|
||||
return pool.obtain(); \
|
||||
} \
|
||||
\
|
||||
static void operator delete(void* ptr, std::size_t sz) { \
|
||||
if(sz != sizeof(TYPE)){ \
|
||||
throw std::runtime_error("wrong object size"); \
|
||||
} \
|
||||
oatpp::base::memory::MemoryPool::free(ptr); \
|
||||
} \
|
||||
\
|
||||
static void* operator new(std::size_t sz, void* entry) { \
|
||||
if(sz != sizeof(TYPE)){ \
|
||||
throw std::runtime_error("wrong object size"); \
|
||||
} \
|
||||
return entry; \
|
||||
} \
|
||||
\
|
||||
static void operator delete(void* ptr, void* entry) { \
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_base_memory_ObjectPool_hpp */
|
26
core/src/collection/LinkedList.cpp
Normal file
26
core/src/collection/LinkedList.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "LinkedList.hpp"
|
||||
|
280
core/src/collection/LinkedList.hpp
Normal file
280
core/src/collection/LinkedList.hpp
Normal file
@ -0,0 +1,280 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_collection_LinkedList_hpp
|
||||
#define oatpp_collection_LinkedList_hpp
|
||||
|
||||
#include "../base/memory/ObjectPool.hpp"
|
||||
|
||||
#include "../base/SharedWrapper.hpp"
|
||||
#include "../base/Controllable.hpp"
|
||||
#include "../base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace collection {
|
||||
|
||||
template<class T>
|
||||
class LinkedList : public base::Controllable {
|
||||
public:
|
||||
OBJECT_POOL(LinkedList_Pool, LinkedList, 32)
|
||||
SHARED_OBJECT_POOL(Shared_LinkedList_Pool, LinkedList, 32)
|
||||
public:
|
||||
|
||||
class LinkedListNode {
|
||||
friend LinkedList;
|
||||
friend oatpp::base::memory::MemoryPool;
|
||||
public:
|
||||
OBJECT_POOL_THREAD_LOCAL(LinkedList_Node_Pool, LinkedListNode, 32)
|
||||
private:
|
||||
T data;
|
||||
LinkedListNode* next;
|
||||
|
||||
protected:
|
||||
|
||||
LinkedListNode(const T& nodeData, LinkedListNode* nextNode)
|
||||
: data(nodeData)
|
||||
, next(nextNode)
|
||||
{}
|
||||
|
||||
~LinkedListNode(){
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
const T& getData(){
|
||||
return data;
|
||||
}
|
||||
|
||||
LinkedListNode* getNext(){
|
||||
return next;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
LinkedListNode* m_first;
|
||||
LinkedListNode* m_last;
|
||||
v_int32 m_count;
|
||||
oatpp::base::memory::MemoryPool& m_itemMemoryPool;
|
||||
|
||||
LinkedListNode* createNode(const T& data, LinkedListNode* next){
|
||||
return new (m_itemMemoryPool.obtain()) LinkedListNode(data, next);
|
||||
}
|
||||
|
||||
void destroyNode(LinkedListNode* node){
|
||||
node->~LinkedListNode();
|
||||
oatpp::base::memory::MemoryPool::free(node);
|
||||
}
|
||||
|
||||
LinkedListNode* getNode(v_int32 index) const{
|
||||
|
||||
if(index >= m_count){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v_int32 i = 0;
|
||||
LinkedListNode* curr = m_first;
|
||||
|
||||
while(curr != nullptr){
|
||||
|
||||
if(i == index){
|
||||
return curr;
|
||||
}
|
||||
|
||||
curr = curr->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
LinkedList()
|
||||
: m_first(nullptr)
|
||||
, m_last(nullptr)
|
||||
, m_count(0)
|
||||
, m_itemMemoryPool(LinkedListNode::LinkedList_Node_Pool::getPool())
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
static std::shared_ptr<LinkedList> createShared(){
|
||||
return Shared_LinkedList_Pool::allocateShared();
|
||||
}
|
||||
|
||||
static std::shared_ptr<LinkedList> copy(LinkedList<T>* other){
|
||||
auto result = createShared();
|
||||
auto curr = other->m_first;
|
||||
while(curr != nullptr){
|
||||
result->pushBack(curr->data);
|
||||
curr = curr->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual ~LinkedList() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void pushFront(const T& data){
|
||||
|
||||
if(m_first == nullptr){
|
||||
LinkedListNode* newNode = createNode(data, nullptr);
|
||||
m_first = newNode;
|
||||
m_last = newNode;
|
||||
}else{
|
||||
LinkedListNode* newNode = createNode(data, m_first);
|
||||
m_first = newNode;
|
||||
}
|
||||
m_count++;
|
||||
|
||||
}
|
||||
|
||||
void pushBack(const T& data){
|
||||
|
||||
LinkedListNode* newNode = createNode(data, nullptr);
|
||||
|
||||
if(m_last == nullptr){
|
||||
m_first = newNode;
|
||||
m_last = newNode;
|
||||
}else{
|
||||
m_last->next = newNode;
|
||||
m_last = newNode;
|
||||
}
|
||||
|
||||
m_count++;
|
||||
|
||||
}
|
||||
|
||||
void pushBackAll(const std::shared_ptr<LinkedList>& list){
|
||||
auto curr = list->getFirstNode();
|
||||
while(curr != nullptr) {
|
||||
pushBack(curr->getData());
|
||||
curr = curr->getNext();
|
||||
}
|
||||
}
|
||||
|
||||
void insertAfterNode(const T& data, LinkedListNode* currentNode){
|
||||
LinkedListNode* node = new LinkedListNode(data, currentNode->next);
|
||||
currentNode->next = node;
|
||||
if(currentNode == m_last){
|
||||
m_last = node;
|
||||
}
|
||||
m_count++;
|
||||
}
|
||||
|
||||
T popFront(){
|
||||
if(m_first != nullptr){
|
||||
LinkedListNode* node = m_first;
|
||||
m_first = m_first->next;
|
||||
if(m_first == nullptr){
|
||||
m_last = nullptr;
|
||||
}
|
||||
m_count --;
|
||||
T result = node->data;
|
||||
destroyNode(node);
|
||||
return result;
|
||||
}else{
|
||||
return T::empty();
|
||||
}
|
||||
}
|
||||
|
||||
const T& getFirst() const{
|
||||
return m_first->data;
|
||||
}
|
||||
|
||||
const T& getLast() const{
|
||||
return m_last->data;
|
||||
}
|
||||
|
||||
const T& get(v_int32 index) const{
|
||||
|
||||
LinkedListNode* node = getNode(index);
|
||||
if(node != nullptr){
|
||||
return node->data;
|
||||
}
|
||||
|
||||
throw std::runtime_error("[oatpp::collection::LinkedList::get(index)]: index out of bounds");
|
||||
|
||||
}
|
||||
|
||||
LinkedListNode* getFirstNode() const {
|
||||
return m_first;
|
||||
}
|
||||
|
||||
v_int32 count() const{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* for each item call a function
|
||||
*
|
||||
* list->forEachNode([](auto item){
|
||||
* // your code here
|
||||
* });
|
||||
*/
|
||||
void forEach(void (*func)(const T& item)) const {
|
||||
auto curr = m_first;
|
||||
while(curr != nullptr) {
|
||||
func(curr->data);
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* for each node call a function
|
||||
*
|
||||
* list->forEachNode([](auto node){
|
||||
* // your code here
|
||||
* });
|
||||
*/
|
||||
void forEachNode(void (*func)(LinkedListNode* node)) const {
|
||||
auto curr = m_first;
|
||||
while(curr != nullptr) {
|
||||
func(curr);
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
void clear(){
|
||||
|
||||
LinkedListNode* curr = m_first;
|
||||
while(curr != nullptr){
|
||||
LinkedListNode* next = curr->next;
|
||||
destroyNode(curr);
|
||||
curr = next;
|
||||
}
|
||||
|
||||
m_first = nullptr;
|
||||
m_last = nullptr;
|
||||
m_count = 0;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_collection_LinkedList_hpp */
|
26
core/src/collection/ListMap.cpp
Normal file
26
core/src/collection/ListMap.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ListMap.hpp"
|
||||
|
277
core/src/collection/ListMap.hpp
Normal file
277
core/src/collection/ListMap.hpp
Normal file
@ -0,0 +1,277 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_collection_ListMap_hpp
|
||||
#define oatpp_collection_ListMap_hpp
|
||||
|
||||
#include "../base/memory/ObjectPool.hpp"
|
||||
#include "../base/Controllable.hpp"
|
||||
|
||||
namespace oatpp { namespace collection {
|
||||
|
||||
template<class K, class V>
|
||||
class ListMap : public oatpp::base::Controllable {
|
||||
public:
|
||||
OBJECT_POOL(ListMap_Pool, ListMap, 32)
|
||||
SHARED_OBJECT_POOL(Shared_ListMap_Pool, ListMap, 32)
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Entry
|
||||
|
||||
class Entry{
|
||||
friend ListMap;
|
||||
public:
|
||||
OBJECT_POOL_THREAD_LOCAL(ListMap_Entry_Pool, Entry, 64)
|
||||
private:
|
||||
K key;
|
||||
V value;
|
||||
Entry* next;
|
||||
protected:
|
||||
Entry(const K& pKey, const V& pValue, Entry* pNext)
|
||||
: key(pKey)
|
||||
, value(pValue)
|
||||
, next(pNext)
|
||||
{}
|
||||
|
||||
~Entry(){
|
||||
}
|
||||
public:
|
||||
|
||||
const K& getKey() const{
|
||||
return key;
|
||||
}
|
||||
|
||||
const V& getValue() const{
|
||||
return value;
|
||||
}
|
||||
|
||||
Entry* getNext() const{
|
||||
return next;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Entry* m_first;
|
||||
Entry* m_last;
|
||||
v_int32 m_count;
|
||||
|
||||
oatpp::base::memory::MemoryPool& m_itemMemoryPool;
|
||||
|
||||
private:
|
||||
|
||||
Entry* createEntry(const K& pKey, const V& pValue, Entry* pNext){
|
||||
return new (m_itemMemoryPool.obtain()) Entry(pKey, pValue, pNext);
|
||||
}
|
||||
|
||||
void destroyEntry(Entry* entry){
|
||||
entry->~Entry();
|
||||
oatpp::base::memory::MemoryPool::free(entry);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Entry* getEntry(v_int32 index) const{
|
||||
|
||||
if(index >= m_count){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v_int32 i = 0;
|
||||
Entry* curr = m_first;
|
||||
|
||||
while(curr != nullptr){
|
||||
|
||||
if(i == index){
|
||||
return curr;
|
||||
}
|
||||
|
||||
curr = curr->next;
|
||||
i++;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
template<class Key>
|
||||
Entry* getEntryByKey(const Key& key) const{
|
||||
|
||||
Entry* curr = m_first;
|
||||
|
||||
while(curr != nullptr){
|
||||
if(key->equals(curr->key)){
|
||||
return curr;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
void addOneEntry(Entry* entry){
|
||||
|
||||
if(m_last == nullptr){
|
||||
m_first = entry;
|
||||
m_last = entry;
|
||||
}else{
|
||||
m_last->next = entry;
|
||||
m_last = entry;
|
||||
}
|
||||
|
||||
m_count++;
|
||||
}
|
||||
|
||||
public:
|
||||
ListMap()
|
||||
: m_first(nullptr)
|
||||
, m_last(nullptr)
|
||||
, m_count(0)
|
||||
, m_itemMemoryPool(Entry::ListMap_Entry_Pool::getPool())
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<ListMap> createShared(){
|
||||
return Shared_ListMap_Pool::allocateShared();
|
||||
}
|
||||
|
||||
~ListMap() override {
|
||||
clear();
|
||||
}
|
||||
|
||||
Entry* put(const K& key, const V& value){
|
||||
Entry* entry = getEntryByKey(key);
|
||||
if(entry != nullptr){
|
||||
if(entry->value != value){
|
||||
entry->value = value;
|
||||
}
|
||||
}else{
|
||||
entry = createEntry(key, value, nullptr);
|
||||
addOneEntry(entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
bool putIfNotExists(const K& key, const V& value){
|
||||
Entry* entry = getEntryByKey(key);
|
||||
if(entry == nullptr){
|
||||
entry = createEntry(key, value, nullptr);
|
||||
addOneEntry(entry);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const Entry* find(const K& key) const{
|
||||
Entry* entry = getEntryByKey<K>(key);
|
||||
if(entry != nullptr){
|
||||
return entry;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const V& get(const K& key, const V& defaultValue) const {
|
||||
Entry* entry = getEntryByKey<K>(key);
|
||||
if(entry != nullptr){
|
||||
return entry->getValue();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/*
|
||||
template <class Key>
|
||||
const Entry* getByKeyTemplate(const Key& key) const{
|
||||
|
||||
Entry* entry = getEntryByKey(key);
|
||||
if(entry != nullptr){
|
||||
return entry;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
V remove(const K& key){
|
||||
|
||||
if(m_first != nullptr){
|
||||
|
||||
if(m_first->key->equals(key)){
|
||||
Entry* next = m_first->next;
|
||||
V result = m_first->value;
|
||||
destroyEntry(m_first);
|
||||
m_first = next;
|
||||
return result;
|
||||
}
|
||||
|
||||
Entry* curr = m_first;
|
||||
Entry* next = m_first->next;
|
||||
|
||||
while(next != nullptr){
|
||||
if(next->key->equals(key)){
|
||||
V result = next->value;
|
||||
curr->next = next->next;
|
||||
destroyEntry(next);
|
||||
return result;
|
||||
}
|
||||
curr = next;
|
||||
next = curr->next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return V::empty();
|
||||
}
|
||||
|
||||
Entry* getFirstEntry() const {
|
||||
return m_first;
|
||||
}
|
||||
|
||||
v_int32 count() const{
|
||||
return m_count;
|
||||
}
|
||||
|
||||
void clear(){
|
||||
|
||||
Entry* curr = m_first;
|
||||
while(curr != nullptr){
|
||||
Entry* next = curr->next;
|
||||
destroyEntry(curr);
|
||||
curr = next;
|
||||
}
|
||||
|
||||
m_first = nullptr;
|
||||
m_last = nullptr;
|
||||
m_count = 0;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_collection_ListMap_hpp */
|
59
core/src/concurrency/Mutex.cpp
Normal file
59
core/src/concurrency/Mutex.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Mutex.hpp"
|
||||
|
||||
#include "../base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace concurrency {
|
||||
|
||||
Mutex::Mutex(){
|
||||
}
|
||||
|
||||
Mutex::~Mutex(){
|
||||
}
|
||||
|
||||
void Mutex::lock(){
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
bool Mutex::tryLock(){
|
||||
return m_mutex.try_lock();
|
||||
}
|
||||
|
||||
void Mutex::unlock(){
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
Mutex::ScopeLock Mutex::createScopeLock(){
|
||||
return ScopeLock(*this);
|
||||
}
|
||||
|
||||
Mutex::ScopeTryLock Mutex::createScopeTryLock(){
|
||||
return ScopeTryLock(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}
|
90
core/src/concurrency/Mutex.hpp
Normal file
90
core/src/concurrency/Mutex.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 concurrency_Mutex_hpp
|
||||
#define concurrency_Mutex_hpp
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace oatpp { namespace concurrency {
|
||||
|
||||
class Mutex{
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
public:
|
||||
|
||||
class ScopeLock{
|
||||
private:
|
||||
Mutex* m_mutex;
|
||||
public:
|
||||
|
||||
ScopeLock(Mutex& mutex) : m_mutex(&mutex) {
|
||||
m_mutex->lock();
|
||||
}
|
||||
|
||||
~ScopeLock(){
|
||||
m_mutex->unlock();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ScopeTryLock{
|
||||
private:
|
||||
Mutex* m_mutex;
|
||||
bool m_isLocked;
|
||||
public:
|
||||
|
||||
ScopeTryLock(Mutex& mutex) : m_mutex(&mutex) {
|
||||
m_isLocked = m_mutex->tryLock();
|
||||
}
|
||||
|
||||
~ScopeTryLock(){
|
||||
if(m_isLocked){
|
||||
m_mutex->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool isLocked(){
|
||||
return m_isLocked;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void lock();
|
||||
bool tryLock();
|
||||
void unlock();
|
||||
|
||||
ScopeLock createScopeLock();
|
||||
ScopeTryLock createScopeTryLock();
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* concurrency_Mutex_hpp */
|
25
core/src/concurrency/Runnable.cpp
Normal file
25
core/src/concurrency/Runnable.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Runnable.hpp"
|
41
core/src/concurrency/Runnable.hpp
Normal file
41
core/src/concurrency/Runnable.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 concurrency_Runnable_hpp
|
||||
#define concurrency_Runnable_hpp
|
||||
|
||||
#include "../base/SharedWrapper.hpp"
|
||||
|
||||
namespace oatpp { namespace concurrency {
|
||||
|
||||
class Runnable {
|
||||
public:
|
||||
|
||||
virtual void run() = 0;
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* concurrency_Runnable_hpp */
|
44
core/src/concurrency/SpinLock.cpp
Normal file
44
core/src/concurrency/SpinLock.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "SpinLock.hpp"
|
||||
|
||||
#include "./Thread.hpp"
|
||||
|
||||
namespace oatpp { namespace concurrency {
|
||||
|
||||
|
||||
SpinLock::SpinLock(Atom& atom)
|
||||
: m_atom(atom)
|
||||
{
|
||||
while (std::atomic_exchange_explicit(&m_atom, true, std::memory_order_acquire)) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
SpinLock::~SpinLock(){
|
||||
std::atomic_store_explicit(&m_atom, false, std::memory_order_release);
|
||||
}
|
||||
|
||||
}}
|
45
core/src/concurrency/SpinLock.hpp
Normal file
45
core/src/concurrency/SpinLock.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_concurrency_SpinLock_hpp
|
||||
#define oatpp_concurrency_SpinLock_hpp
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
namespace oatpp { namespace concurrency {
|
||||
|
||||
class SpinLock {
|
||||
public:
|
||||
typedef std::atomic<bool> Atom;
|
||||
private:
|
||||
Atom& m_atom;
|
||||
public:
|
||||
SpinLock(Atom& atom);
|
||||
~SpinLock();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_concurrency_SpinLock_hpp */
|
26
core/src/concurrency/Thread.cpp
Normal file
26
core/src/concurrency/Thread.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Thread.hpp"
|
||||
|
72
core/src/concurrency/Thread.hpp
Normal file
72
core/src/concurrency/Thread.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_concurrency_Thread_hpp
|
||||
#define oatpp_concurrency_Thread_hpp
|
||||
|
||||
#include "./Runnable.hpp"
|
||||
|
||||
#include "../base/memory/ObjectPool.hpp"
|
||||
|
||||
#include "../base/Controllable.hpp"
|
||||
#include "../base/SharedWrapper.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
namespace oatpp { namespace concurrency {
|
||||
|
||||
class Thread : public base::Controllable {
|
||||
public:
|
||||
OBJECT_POOL(Thread_Pool, Thread, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Thread_Pool, Thread, 32)
|
||||
private:
|
||||
std::thread m_thread;
|
||||
public:
|
||||
|
||||
Thread(const std::shared_ptr<Runnable>& runnable) {
|
||||
m_thread = std::thread([runnable]{
|
||||
runnable->run();
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static std::shared_ptr<Thread> createShared(const std::shared_ptr<Runnable>& runnable){
|
||||
return Shared_Thread_Pool::allocateShared(runnable);
|
||||
}
|
||||
|
||||
void join(){
|
||||
m_thread.join();
|
||||
}
|
||||
|
||||
void detach(){
|
||||
m_thread.detach();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* concurrency_Thread_hpp */
|
31
core/src/data/buffer/IOBuffer.cpp
Normal file
31
core/src/data/buffer/IOBuffer.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "IOBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace buffer {
|
||||
|
||||
const v_int32 IOBuffer::BUFFER_SIZE = 4096;
|
||||
|
||||
}}}
|
74
core/src/data/buffer/IOBuffer.hpp
Normal file
74
core/src/data/buffer/IOBuffer.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_buffer_IOBuffer_hpp
|
||||
#define oatpp_data_buffer_IOBuffer_hpp
|
||||
|
||||
#include "../../base/memory/ObjectPool.hpp"
|
||||
#include "../../base/Controllable.hpp"
|
||||
#include "../../base/SharedWrapper.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace buffer {
|
||||
|
||||
class IOBuffer : public oatpp::base::Controllable {
|
||||
public:
|
||||
OBJECT_POOL(IOBuffer_Pool, IOBuffer, 32)
|
||||
SHARED_OBJECT_POOL(Shared_IOBuffer_Pool, IOBuffer, 32)
|
||||
public:
|
||||
static const v_int32 BUFFER_SIZE;
|
||||
private:
|
||||
// TODO FastAlloc
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getBufferPool(){
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool pool("IOBuffer_Buffer_Pool", BUFFER_SIZE, 32);
|
||||
return pool;
|
||||
}
|
||||
private:
|
||||
void* m_entry;
|
||||
public:
|
||||
IOBuffer()
|
||||
: m_entry(getBufferPool().obtain())
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<IOBuffer> createShared(){
|
||||
return Shared_IOBuffer_Pool::allocateShared();
|
||||
}
|
||||
|
||||
~IOBuffer() {
|
||||
oatpp::base::memory::MemoryPool::free(m_entry);
|
||||
}
|
||||
|
||||
void* getData(){
|
||||
return m_entry;
|
||||
}
|
||||
|
||||
v_int32 getSize(){
|
||||
return BUFFER_SIZE;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_data_buffer_IOBuffer_hpp */
|
25
core/src/data/mapping/ObjectMapper.cpp
Normal file
25
core/src/data/mapping/ObjectMapper.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ObjectMapper.hpp"
|
89
core/src/data/mapping/ObjectMapper.hpp
Normal file
89
core/src/data/mapping/ObjectMapper.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_ObjectMapper_hpp
|
||||
#define oatpp_data_mapping_ObjectMapper_hpp
|
||||
|
||||
#include "./type/Object.hpp"
|
||||
#include "./type/Object.hpp"
|
||||
#include "./type/Type.hpp"
|
||||
|
||||
#include "../stream/ChunkedBuffer.hpp"
|
||||
#include "../stream/Stream.hpp"
|
||||
|
||||
#include "../../parser/ParsingCaret.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping {
|
||||
|
||||
class ObjectMapper {
|
||||
public:
|
||||
class Info {
|
||||
public:
|
||||
Info(const char* _http_content_type)
|
||||
: http_content_type(_http_content_type)
|
||||
{}
|
||||
const char* const http_content_type;
|
||||
};
|
||||
private:
|
||||
Info m_info;
|
||||
public:
|
||||
|
||||
ObjectMapper(const Info& info)
|
||||
: m_info(info)
|
||||
{}
|
||||
|
||||
Info& getInfo(){
|
||||
return m_info;
|
||||
}
|
||||
|
||||
virtual void write(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
|
||||
const type::VariantWrapper& variant) = 0;
|
||||
|
||||
virtual type::AbstractSharedWrapper read(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const type::Type* const type) = 0;
|
||||
|
||||
std::shared_ptr<oatpp::base::String> writeToString(const type::VariantWrapper& variant){
|
||||
auto stream = stream::ChunkedBuffer::createShared();
|
||||
write(stream, variant);
|
||||
return stream->toString();
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
typename Class::SharedWrapper readFromCaret(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret) {
|
||||
auto type = Class::SharedWrapper::Class::getType();
|
||||
return oatpp::base::static_wrapper_cast<typename Class::SharedWrapper::ObjectType>(read(caret, type));
|
||||
}
|
||||
|
||||
template<class Class>
|
||||
typename Class::SharedWrapper readFromString(const oatpp::base::String::SharedWrapper& str) {
|
||||
auto type = Class::SharedWrapper::Class::getType();
|
||||
auto caret = oatpp::parser::ParsingCaret::createShared(str.getPtr());
|
||||
return oatpp::base::static_wrapper_cast<typename Class::SharedWrapper::ObjectType>(read(caret, type));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_data_mapping_ObjectMapper_hpp */
|
25
core/src/data/mapping/type/List.cpp
Normal file
25
core/src/data/mapping/type/List.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./List.hpp"
|
106
core/src/data/mapping/type/List.hpp
Normal file
106
core/src/data/mapping/type/List.hpp
Normal file
@ -0,0 +1,106 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_type_List_hpp
|
||||
#define oatpp_data_type_List_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "../../../collection/LinkedList.hpp"
|
||||
|
||||
#include "../../../base/memory/ObjectPool.hpp"
|
||||
#include "../../../base/Controllable.hpp"
|
||||
#include "../../../base/String.hpp"
|
||||
#include "../../../base/SharedWrapper.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractList {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "List";
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class List; // FWD
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
class List : public oatpp::collection::LinkedList<T> {
|
||||
friend __class::List<T>;
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::SharedWrapper<List, __class::List<T>> SharedWrapper;
|
||||
public:
|
||||
OBJECT_POOL(DTO_LIST_POOL, List, 32)
|
||||
SHARED_OBJECT_POOL(SHARED_DTO_LIST_POOL, List, 32)
|
||||
protected:
|
||||
|
||||
static AbstractSharedWrapper Z__CLASS_OBJECT_CREATOR(){
|
||||
return AbstractSharedWrapper(SHARED_DTO_LIST_POOL::allocateShared(), Z__CLASS_GET_TYPE());
|
||||
}
|
||||
|
||||
static Type* Z__CLASS_GET_TYPE(){
|
||||
static Type type(__class::AbstractList::CLASS_NAME, &Z__CLASS_OBJECT_CREATOR);
|
||||
if(type.params.empty()){
|
||||
type.params.push_back(T::Class::getType());
|
||||
}
|
||||
return &type;
|
||||
}
|
||||
|
||||
public:
|
||||
List()
|
||||
{}
|
||||
public:
|
||||
|
||||
static SharedWrapper createShared(){
|
||||
return SharedWrapper(SHARED_DTO_LIST_POOL::allocateShared());
|
||||
}
|
||||
|
||||
virtual void addPolymorphicItem(const AbstractSharedWrapper& item){
|
||||
auto ptr = std::static_pointer_cast<typename T::ObjectType>(item.getPtr());
|
||||
this->pushBack(T(ptr, item.valueType));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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());
|
||||
return type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* List_hpp */
|
25
core/src/data/mapping/type/Object.cpp
Normal file
25
core/src/data/mapping/type/Object.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Object.hpp"
|
86
core/src/data/mapping/type/Object.hpp
Normal file
86
core/src/data/mapping/type/Object.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_type_Object_hpp
|
||||
#define oatpp_data_type_Object_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "./Primitive.hpp"
|
||||
#include "./List.hpp"
|
||||
|
||||
#include "../../../base/memory/ObjectPool.hpp"
|
||||
#include "../../../base/Controllable.hpp"
|
||||
#include "../../../base/String.hpp"
|
||||
#include "../../../base/SharedWrapper.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class AbstractObject {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Object";
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class Object : public AbstractObject {
|
||||
public:
|
||||
|
||||
static Type* getType(){
|
||||
static Type* type = static_cast<Type*>(T::Z__CLASS_GET_TYPE());
|
||||
return type;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class Object : public oatpp::base::Controllable {
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::StringSharedWrapper String;
|
||||
typedef oatpp::data::mapping::type::Int32::SharedWrapper Int32;
|
||||
typedef oatpp::data::mapping::type::Int64::SharedWrapper Int64;
|
||||
typedef oatpp::data::mapping::type::Float32::SharedWrapper Float32;
|
||||
typedef oatpp::data::mapping::type::Float64::SharedWrapper Float64;
|
||||
typedef oatpp::data::mapping::type::Boolean::SharedWrapper Boolean;
|
||||
template <class T>
|
||||
using List = oatpp::data::mapping::type::List<T>;
|
||||
protected:
|
||||
static Type::Properties* Z__CLASS_EXTEND(Type::Properties* map, Type::Properties* extensionMap) {
|
||||
map->insert(extensionMap->begin(), extensionMap->end());
|
||||
return extensionMap;
|
||||
}
|
||||
public:
|
||||
|
||||
static oatpp::data::mapping::type::Type::Properties* Z__CLASS_GET_FIELDS_MAP(){
|
||||
static oatpp::data::mapping::type::Type::Properties map;
|
||||
return ↦
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_data_type_Object_hpp */
|
65
core/src/data/mapping/type/Primitive.cpp
Normal file
65
core/src/data/mapping/type/Primitive.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Primitive.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
StringSharedWrapper::StringSharedWrapper(const std::shared_ptr<oatpp::base::String>& ptr, const type::Type* const valueType)
|
||||
: oatpp::data::mapping::type::SharedWrapper<oatpp::base::String, __class::String>()
|
||||
{
|
||||
if(type::__class::String::getType() != valueType) {
|
||||
throw std::runtime_error("Value type does not match");
|
||||
}
|
||||
}
|
||||
|
||||
StringSharedWrapper::operator AbstractSharedWrapper() {
|
||||
return AbstractSharedWrapper(m_ptr, __class::String::getType());
|
||||
}
|
||||
|
||||
namespace __class {
|
||||
|
||||
type::Int32::SharedWrapper Int32::parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success) {
|
||||
return utils::conversion::strToInt32(str, success);
|
||||
}
|
||||
|
||||
type::Int64::SharedWrapper Int64::parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success) {
|
||||
return utils::conversion::strToInt64(str, success);
|
||||
}
|
||||
|
||||
type::Float32::SharedWrapper Float32::parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success) {
|
||||
return utils::conversion::strToFloat32(str, success);
|
||||
}
|
||||
|
||||
type::Float64::SharedWrapper Float64::parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success) {
|
||||
return utils::conversion::strToFloat64(str, success);
|
||||
}
|
||||
|
||||
type::Boolean::SharedWrapper Boolean::parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success) {
|
||||
return utils::conversion::strToBool(str, success);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
329
core/src/data/mapping/type/Primitive.hpp
Normal file
329
core/src/data/mapping/type/Primitive.hpp
Normal file
@ -0,0 +1,329 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_type_Primitive_hpp
|
||||
#define oatpp_data_type_Primitive_hpp
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "../../../utils/ConversionUtils.hpp"
|
||||
|
||||
#include "../../../base/memory/ObjectPool.hpp"
|
||||
#include "../../../base/Controllable.hpp"
|
||||
#include "../../../base/String.hpp"
|
||||
|
||||
#include "../../../base/SharedWrapper.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
class String; // FWD
|
||||
class Int32; // FWD
|
||||
class Int64; // FWD
|
||||
class Float32; // FWD
|
||||
class Float64; // FWD
|
||||
class Boolean; // FWD
|
||||
|
||||
}
|
||||
|
||||
class StringSharedWrapper : public oatpp::data::mapping::type::SharedWrapper<oatpp::base::String, __class::String> {
|
||||
public:
|
||||
StringSharedWrapper(const std::shared_ptr<oatpp::base::String>& ptr, const type::Type* const valueType);
|
||||
public:
|
||||
|
||||
StringSharedWrapper() {}
|
||||
|
||||
StringSharedWrapper(const std::shared_ptr<oatpp::base::String>& ptr)
|
||||
: type::SharedWrapper<oatpp::base::String, __class::String>(ptr)
|
||||
{}
|
||||
|
||||
StringSharedWrapper(std::shared_ptr<oatpp::base::String>&& ptr)
|
||||
: type::SharedWrapper<oatpp::base::String, __class::String>(std::move(ptr))
|
||||
{}
|
||||
|
||||
StringSharedWrapper(const char* str)
|
||||
: type::SharedWrapper<oatpp::base::String, __class::String>(oatpp::base::String::createFromCString(str))
|
||||
{}
|
||||
|
||||
StringSharedWrapper(const oatpp::base::SharedWrapper<oatpp::base::String>& other)
|
||||
: type::SharedWrapper<oatpp::base::String, __class::String>(other)
|
||||
{}
|
||||
|
||||
StringSharedWrapper(oatpp::base::SharedWrapper<oatpp::base::String>&& other)
|
||||
: type::SharedWrapper<oatpp::base::String, __class::String>(std::move(other))
|
||||
{}
|
||||
|
||||
StringSharedWrapper& operator = (const char* str) {
|
||||
m_ptr = oatpp::base::String::createFromCString(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringSharedWrapper& operator = (const oatpp::base::SharedWrapper<oatpp::base::String>& other){
|
||||
oatpp::base::SharedWrapper<oatpp::base::String>::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringSharedWrapper& operator = (oatpp::base::SharedWrapper<oatpp::base::String>&& other){
|
||||
oatpp::base::SharedWrapper<oatpp::base::String>::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringSharedWrapper operator + (const char* str) const{
|
||||
return oatpp::base::String::createSharedConcatenated(m_ptr.get()->getData(), m_ptr.get()->getSize(), str, (v_int32) std::strlen(str));
|
||||
}
|
||||
|
||||
StringSharedWrapper operator + (const oatpp::base::SharedWrapper<oatpp::base::String>& other) const{
|
||||
return oatpp::base::String::createSharedConcatenated(m_ptr.get()->getData(), m_ptr.get()->getSize(), other.get()->getData(), other.get()->getSize());
|
||||
}
|
||||
|
||||
operator AbstractSharedWrapper();
|
||||
|
||||
static const StringSharedWrapper& empty(){
|
||||
static StringSharedWrapper empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename ValueType, class Clazz>
|
||||
class Primitive : public oatpp::base::Controllable {
|
||||
public:
|
||||
OBJECT_POOL(Primitive_Type_Pool, Primitive, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Primitive_Type_Pool, Primitive, 32)
|
||||
public:
|
||||
|
||||
class SharedWrapper : public oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz> {
|
||||
public:
|
||||
SharedWrapper(const std::shared_ptr<Primitive>& ptr, const type::Type* const valueType)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>(ptr)
|
||||
{
|
||||
if(Clazz::getType() != valueType){
|
||||
throw std::runtime_error("Value type does not match");
|
||||
}
|
||||
}
|
||||
public:
|
||||
|
||||
SharedWrapper()
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>()
|
||||
{}
|
||||
|
||||
SharedWrapper(const std::shared_ptr<Primitive>& ptr)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>(ptr)
|
||||
{}
|
||||
|
||||
SharedWrapper(std::shared_ptr<Primitive>&& ptr)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>(std::move(ptr))
|
||||
{}
|
||||
|
||||
SharedWrapper(const SharedWrapper& other)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>(other)
|
||||
{}
|
||||
|
||||
SharedWrapper(SharedWrapper&& other)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>(std::move(other))
|
||||
{}
|
||||
|
||||
SharedWrapper(const VariantWrapper& variant)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>()
|
||||
{
|
||||
*this = variant;
|
||||
}
|
||||
|
||||
SharedWrapper(const ValueType& value)
|
||||
: oatpp::data::mapping::type::SharedWrapper<Primitive, Clazz>(Primitive::createShared(value))
|
||||
{}
|
||||
|
||||
SharedWrapper& operator = (const ValueType& value){
|
||||
if(this->isNull()){
|
||||
this->m_ptr = Primitive::createShared(value);
|
||||
} else {
|
||||
this->m_ptr.get()->setValue(value);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedWrapper& operator=(const VariantWrapper& variant) {
|
||||
if(this->valueType != variant.getValueType()) {
|
||||
OATPP_LOGE("[oatpp::data::mapping::type::Primitive::SharedWrapper]", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::Primitive::SharedWrapper]: Invalid class cast");
|
||||
}
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable>::operator=(variant);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline operator ValueType(){
|
||||
return this->m_object->getValue();
|
||||
}
|
||||
|
||||
static const SharedWrapper& empty(){
|
||||
static SharedWrapper result;
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
ValueType m_value;
|
||||
|
||||
public:
|
||||
Primitive(const ValueType& value)
|
||||
: m_value(value)
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<Primitive> createShared(const ValueType& value){
|
||||
return Shared_Primitive_Type_Pool::allocateShared(value);
|
||||
}
|
||||
|
||||
static std::shared_ptr<Controllable> createAbstract(const ValueType& value){
|
||||
return std::static_pointer_cast<Controllable>(Shared_Primitive_Type_Pool::allocateShared(value));
|
||||
}
|
||||
|
||||
void setValue(const ValueType& value) {
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
ValueType getValue() {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef Primitive<v_int32, __class::Int32> Int32;
|
||||
typedef Primitive<v_int64, __class::Int64> Int64;
|
||||
typedef Primitive<v_float32, __class::Float32> Float32;
|
||||
typedef Primitive<v_float64, __class::Float64> Float64;
|
||||
typedef Primitive<bool, __class::Boolean> Boolean;
|
||||
|
||||
namespace __class {
|
||||
|
||||
class String {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "String";
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
static type::StringSharedWrapper parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success){
|
||||
success = true;
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Int32 {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Int32";
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
static type::Int32::SharedWrapper parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success);
|
||||
|
||||
};
|
||||
|
||||
class Int64 {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Int64";
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
static type::Int64::SharedWrapper parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success);
|
||||
|
||||
};
|
||||
|
||||
class Float32 {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Float32";
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
static type::Float32::SharedWrapper parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success);
|
||||
|
||||
};
|
||||
|
||||
class Float64 {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Float64";
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
static type::Float64::SharedWrapper parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success);
|
||||
|
||||
};
|
||||
|
||||
class Boolean {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Boolean";
|
||||
|
||||
static Type* getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
static type::Boolean::SharedWrapper parseFromString(const oatpp::base::String::SharedWrapper& str, bool& success);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
base::SharedWrapper<base::String>
|
||||
primitiveToStr(const oatpp::data::mapping::type::PolymorphicWrapper<T>& primitive) {
|
||||
auto type = primitive.valueType;
|
||||
if(type == oatpp::data::mapping::type::__class::String::getType()) {
|
||||
return std::static_pointer_cast<base::String>(primitive.getPtr());
|
||||
} else if(type == oatpp::data::mapping::type::__class::Int32::getType()) {
|
||||
return utils::conversion::int32ToStr(static_cast<oatpp::data::mapping::type::Int32*>(primitive.get())->getValue());
|
||||
} else if(type == oatpp::data::mapping::type::__class::Int64::getType()) {
|
||||
return utils::conversion::int64ToStr(static_cast<oatpp::data::mapping::type::Int64*>(primitive.get())->getValue());
|
||||
} else if(type == oatpp::data::mapping::type::__class::Float32::getType()) {
|
||||
return utils::conversion::float32ToStr(static_cast<oatpp::data::mapping::type::Float32*>(primitive.get())->getValue());
|
||||
} else if(type == oatpp::data::mapping::type::__class::Float64::getType()) {
|
||||
return utils::conversion::float64ToStr(static_cast<oatpp::data::mapping::type::Float64*>(primitive.get())->getValue());
|
||||
} else if(type == oatpp::data::mapping::type::__class::Boolean::getType()) {
|
||||
return utils::conversion::boolToStr(static_cast<oatpp::data::mapping::type::Boolean*>(primitive.get())->getValue());
|
||||
}
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::primitiveToStr]: Invalid primitive type");
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_base_controllable_PrimitiveDataTypes_hpp */
|
39
core/src/data/mapping/type/Type.cpp
Normal file
39
core/src/data/mapping/type/Type.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Type.hpp"
|
||||
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
|
||||
Type* Void::getType(){
|
||||
static Type type(CLASS_NAME);
|
||||
return &type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
294
core/src/data/mapping/type/Type.hpp
Normal file
294
core/src/data/mapping/type/Type.hpp
Normal file
@ -0,0 +1,294 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_type_Type_hpp
|
||||
#define oatpp_data_type_Type_hpp
|
||||
|
||||
#include "../../../base/SharedWrapper.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class Type; // FWD
|
||||
|
||||
namespace __class {
|
||||
class Void {
|
||||
public:
|
||||
constexpr static const char* const CLASS_NAME = "Void";
|
||||
static Type* getType();
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class PolymorphicWrapper : public oatpp::base::SharedWrapper<T> {
|
||||
public:
|
||||
typedef T ObjectType;
|
||||
public:
|
||||
typedef __class::Void Class;
|
||||
public:
|
||||
PolymorphicWrapper(const oatpp::base::SharedWrapper<T>& other, const Type* const type)
|
||||
: oatpp::base::SharedWrapper<T>(other)
|
||||
, valueType(type)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(oatpp::base::SharedWrapper<T>&& other, const Type* const type)
|
||||
: oatpp::base::SharedWrapper<T>(std::move(other))
|
||||
, valueType(type)
|
||||
{}
|
||||
public:
|
||||
|
||||
PolymorphicWrapper()
|
||||
: oatpp::base::SharedWrapper<T>()
|
||||
, valueType(Class::getType())
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(const Type* const type)
|
||||
: oatpp::base::SharedWrapper<T>()
|
||||
, valueType(type)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(const std::shared_ptr<T>& ptr, const Type* const type)
|
||||
: oatpp::base::SharedWrapper<T>(ptr)
|
||||
, valueType(type)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(const PolymorphicWrapper& other)
|
||||
: oatpp::base::SharedWrapper<T>(other)
|
||||
, valueType(other.valueType)
|
||||
{}
|
||||
|
||||
PolymorphicWrapper(PolymorphicWrapper&& other)
|
||||
: oatpp::base::SharedWrapper<T>(std::move(other))
|
||||
, valueType(other.valueType)
|
||||
{}
|
||||
|
||||
static PolymorphicWrapper empty(){
|
||||
return PolymorphicWrapper();
|
||||
}
|
||||
|
||||
PolymorphicWrapper& operator=(const oatpp::base::SharedWrapper<T>& other){
|
||||
oatpp::base::SharedWrapper<T>::operator = (other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolymorphicWrapper& operator=(const oatpp::base::SharedWrapper<T>&& other){
|
||||
oatpp::base::SharedWrapper<T>::operator = (std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolymorphicWrapper& operator=(const PolymorphicWrapper<T>& other){
|
||||
oatpp::base::SharedWrapper<T>::operator = (other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PolymorphicWrapper& operator=(const PolymorphicWrapper<T>&& other){
|
||||
oatpp::base::SharedWrapper<T>::operator = (std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Type* const valueType;
|
||||
|
||||
};
|
||||
|
||||
template <class T, class Clazz>
|
||||
class SharedWrapper : public PolymorphicWrapper<T>{
|
||||
public:
|
||||
typedef T ObjectType;
|
||||
public:
|
||||
typedef Clazz Class;
|
||||
public:
|
||||
SharedWrapper(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:
|
||||
|
||||
SharedWrapper()
|
||||
: PolymorphicWrapper<T>(Class::getType())
|
||||
{}
|
||||
|
||||
SharedWrapper(const std::shared_ptr<T>& ptr)
|
||||
: PolymorphicWrapper<T>(ptr, Class::getType())
|
||||
{}
|
||||
|
||||
SharedWrapper(const oatpp::base::SharedWrapper<T>& other)
|
||||
: PolymorphicWrapper<T>(other, Class::getType())
|
||||
{}
|
||||
|
||||
SharedWrapper(oatpp::base::SharedWrapper<T>&& other)
|
||||
: PolymorphicWrapper<T>(std::move(other), Class::getType())
|
||||
{}
|
||||
|
||||
static SharedWrapper empty(){
|
||||
return SharedWrapper();
|
||||
}
|
||||
|
||||
SharedWrapper& operator=(const oatpp::base::SharedWrapper<T>& other){
|
||||
if(this->valueType != other.valueType){
|
||||
OATPP_LOGE("SharedWrapper", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::SharedWrapper]: Invalid class cast");
|
||||
}
|
||||
PolymorphicWrapper<T>::operator = (other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SharedWrapper& operator=(const oatpp::base::SharedWrapper<T>&& other){
|
||||
if(this->valueType != other.valueType){
|
||||
OATPP_LOGE("SharedWrapper", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::SharedWrapper]: Invalid class cast");
|
||||
}
|
||||
PolymorphicWrapper<T>::operator = (std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class VariantWrapper : public oatpp::base::SharedWrapper<oatpp::base::Controllable> {
|
||||
protected:
|
||||
const Type* m_valueType;
|
||||
public:
|
||||
|
||||
explicit VariantWrapper()
|
||||
: oatpp::base::SharedWrapper<oatpp::base::Controllable>()
|
||||
, m_valueType(nullptr)
|
||||
{}
|
||||
|
||||
VariantWrapper(const VariantWrapper& other)
|
||||
: oatpp::base::SharedWrapper<oatpp::base::Controllable>(other)
|
||||
, m_valueType(other.m_valueType)
|
||||
{}
|
||||
|
||||
template <class T, class Clazz>
|
||||
VariantWrapper(const oatpp::data::mapping::type::SharedWrapper<T, Clazz>& other)
|
||||
: oatpp::base::SharedWrapper<oatpp::base::Controllable>(std::static_pointer_cast<oatpp::base::Controllable>(other.getPtr()))
|
||||
, m_valueType(other.valueType)
|
||||
{}
|
||||
|
||||
static VariantWrapper empty(){
|
||||
return VariantWrapper();
|
||||
}
|
||||
|
||||
const Type* const getValueType() const {
|
||||
return m_valueType;
|
||||
}
|
||||
|
||||
template <class T, class Clazz>
|
||||
VariantWrapper& operator=(const oatpp::data::mapping::type::SharedWrapper<T, Clazz>& other){
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable>::operator = (other);
|
||||
this->m_valueType = other.valueType;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T, class Clazz>
|
||||
inline operator oatpp::data::mapping::type::SharedWrapper<T, Clazz>(){
|
||||
if(Clazz::getType() != m_valueType){
|
||||
OATPP_LOGE("VariantWrapper", "Invalid class cast");
|
||||
throw std::runtime_error("[oatpp::data::mapping::type::VariantWrapper]: Invalid class cast");
|
||||
}
|
||||
return oatpp::data::mapping::type::SharedWrapper<T, Clazz>(m_ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef PolymorphicWrapper<oatpp::base::Controllable> AbstractSharedWrapper;
|
||||
|
||||
class Type {
|
||||
public:
|
||||
typedef AbstractSharedWrapper (*Creator)();
|
||||
public:
|
||||
class Property; // FWD
|
||||
typedef std::unordered_map<std::string, Property*> Properties;
|
||||
public:
|
||||
|
||||
class Property {
|
||||
private:
|
||||
const v_int64 offset;
|
||||
public:
|
||||
|
||||
Property(std::unordered_map<std::string, Property*>* pMap,
|
||||
v_int64 pOffset,
|
||||
const char* pName,
|
||||
Type* pType)
|
||||
: offset(pOffset)
|
||||
, name(pName)
|
||||
, type(pType)
|
||||
{
|
||||
pMap->insert({name, this});
|
||||
}
|
||||
|
||||
const char* const name;
|
||||
const Type* const type;
|
||||
|
||||
void set(void* object, const oatpp::base::SharedWrapper<oatpp::base::Controllable>& value) {
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable>* property =
|
||||
(oatpp::base::SharedWrapper<oatpp::base::Controllable>*)(((v_int64) object) + offset);
|
||||
*property = value;
|
||||
}
|
||||
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable> get(void* object) {
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable>* property =
|
||||
(oatpp::base::SharedWrapper<oatpp::base::Controllable>*)(((v_int64) object) + offset);
|
||||
return *property;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Type(const char* pName)
|
||||
: name(pName)
|
||||
, creator(nullptr)
|
||||
, properties(nullptr)
|
||||
{}
|
||||
|
||||
Type(const char* pName, Creator pCreator)
|
||||
: name(pName)
|
||||
, creator(pCreator)
|
||||
, properties(nullptr)
|
||||
{}
|
||||
|
||||
Type(const char* pName, Creator pCreator, Properties* pProperties)
|
||||
: name(pName)
|
||||
, creator(pCreator)
|
||||
, properties(pProperties)
|
||||
{}
|
||||
|
||||
const char* const name;
|
||||
std::list<Type*> params;
|
||||
|
||||
const Creator creator;
|
||||
|
||||
const Properties* const properties;
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_data_type_Type_hpp */
|
112
core/src/data/mapping/type/macro/zzz_macro_define_DTO_.hpp
Normal file
112
core/src/data/mapping/type/macro/zzz_macro_define_DTO_.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "../../../../macro/basic.hpp"
|
||||
#include "../../../../macro/codegen.hpp"
|
||||
|
||||
// Defaults
|
||||
|
||||
#define DTO_INIT(TYPE_NAME, TYPE_EXTEND) \
|
||||
\
|
||||
public: \
|
||||
typedef TYPE_NAME Z__CLASS; \
|
||||
typedef oatpp::data::mapping::type::SharedWrapper<Z__CLASS, oatpp::data::mapping::type::__class::Object<Z__CLASS>> SharedWrapper; \
|
||||
public: \
|
||||
OBJECT_POOL(DTO_OBJECT_POOL_##TYPE_NAME, TYPE_NAME, 32) \
|
||||
SHARED_OBJECT_POOL(SHARED_DTO_OBJECT_POOL_##TYPE_NAME, TYPE_NAME, 32) \
|
||||
public: \
|
||||
TYPE_NAME() \
|
||||
{ \
|
||||
Z__CLASS_EXTEND(Z__CLASS::Z__CLASS_GET_FIELDS_MAP(), TYPE_EXTEND::Z__CLASS_GET_FIELDS_MAP()); \
|
||||
} \
|
||||
public: \
|
||||
\
|
||||
static SharedWrapper createShared(){ \
|
||||
return SharedWrapper(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::AbstractSharedWrapper Z__CLASS_OBJECT_CREATOR(){ \
|
||||
return oatpp::data::mapping::type::AbstractSharedWrapper(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_NAME, \
|
||||
&Z__CLASS_OBJECT_CREATOR, \
|
||||
Z__CLASS_GET_FIELDS_MAP()); \
|
||||
return &type; \
|
||||
}
|
||||
|
||||
// Fields
|
||||
|
||||
#define OATPP_MACRO_DTO_FIELD_0(TYPE, NAME, LIST) \
|
||||
\
|
||||
oatpp::data::mapping::type::Type::Property* Z__CLASS_FIELD_##NAME = \
|
||||
Z__CLASS_GET_FIELD_##NAME(static_cast<oatpp::base::Controllable*>(this), \
|
||||
(oatpp::base::SharedWrapper<oatpp::base::Controllable>*)(&NAME)); \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Property* \
|
||||
Z__CLASS_GET_FIELD_##NAME(oatpp::base::Controllable* _this, \
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable>* _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_1(TYPE, NAME, LIST) \
|
||||
\
|
||||
oatpp::data::mapping::type::Type::Property* Z__CLASS_FIELD_##NAME = \
|
||||
Z__CLASS_GET_FIELD_##NAME(static_cast<oatpp::base::Controllable*>(this), \
|
||||
(oatpp::base::SharedWrapper<oatpp::base::Controllable>*)(&NAME)); \
|
||||
\
|
||||
static oatpp::data::mapping::type::Type::Property* \
|
||||
Z__CLASS_GET_FIELD_##NAME(oatpp::base::Controllable* _this, \
|
||||
oatpp::base::SharedWrapper<oatpp::base::Controllable>* _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, \
|
||||
OATPP_MACRO_FIRSTARG LIST, \
|
||||
TYPE::Class::getType()); \
|
||||
return field; \
|
||||
} \
|
||||
\
|
||||
TYPE NAME
|
||||
|
||||
#define OATPP_MACRO_DTO_FIELD_(X, TYPE, NAME, LIST) OATPP_MACRO_DTO_FIELD_##X(TYPE, NAME, LIST)
|
||||
#define OATPP_MACRO_DTO_FIELD__(X, TYPE, NAME, LIST) OATPP_MACRO_DTO_FIELD_(X, TYPE, NAME, LIST)
|
||||
#define OATPP_MACRO_DTO_FIELD___(TYPE, NAME, LIST) OATPP_MACRO_DTO_FIELD__(OATPP_MACRO_HAS_ARGS LIST, TYPE, NAME, LIST)
|
||||
|
||||
#define DTO_FIELD(TYPE, NAME, ...) \
|
||||
OATPP_MACRO_DTO_FIELD___(TYPE, NAME, (__VA_ARGS__))
|
||||
|
||||
///
|
37
core/src/data/mapping/type/macro/zzz_macro_undef_DTO_.hpp
Normal file
37
core/src/data/mapping/type/macro/zzz_macro_undef_DTO_.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#undef DTO_INIT
|
||||
|
||||
// Fields
|
||||
|
||||
#undef OATPP_MACRO_DTO_FIELD_0
|
||||
|
||||
#undef OATPP_MACRO_DTO_FIELD_1
|
||||
|
||||
#undef OATPP_MACRO_DTO_FIELD_
|
||||
#undef OATPP_MACRO_DTO_FIELD__
|
||||
#undef OATPP_MACRO_DTO_FIELD___
|
||||
|
||||
#undef DTO_FIELD
|
247
core/src/data/stream/ChunkedBuffer.cpp
Normal file
247
core/src/data/stream/ChunkedBuffer.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ChunkedBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
const char* const ChunkedBuffer::CHUNK_POOL_NAME = "ChunkedBuffer_Chunk_Pool";
|
||||
|
||||
const os::io::Library::v_size ChunkedBuffer::CHUNK_ENTRY_SIZE_INDEX_SHIFT = 11;
|
||||
const os::io::Library::v_size ChunkedBuffer::CHUNK_ENTRY_SIZE =
|
||||
(1 << ChunkedBuffer::CHUNK_ENTRY_SIZE_INDEX_SHIFT);
|
||||
const os::io::Library::v_size ChunkedBuffer::CHUNK_CHUNK_SIZE = 32;
|
||||
|
||||
ChunkedBuffer::ChunkEntry* ChunkedBuffer::obtainNewEntry(){
|
||||
auto result = new ChunkEntry(getSegemntPool().obtain(), nullptr);
|
||||
if(m_firstEntry == nullptr) {
|
||||
m_firstEntry = result;
|
||||
} else {
|
||||
m_lastEntry->next = result;
|
||||
}
|
||||
m_lastEntry = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ChunkedBuffer::freeEntry(ChunkEntry* entry){
|
||||
oatpp::base::memory::MemoryPool::free(entry->chunk);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
os::io::Library::v_size ChunkedBuffer::writeToEntry(ChunkEntry* entry,
|
||||
const void *data,
|
||||
os::io::Library::v_size count,
|
||||
os::io::Library::v_size& outChunkPos) {
|
||||
if(count >= CHUNK_ENTRY_SIZE){
|
||||
std::memcpy(entry->chunk, data, CHUNK_ENTRY_SIZE);
|
||||
outChunkPos = 0;
|
||||
return CHUNK_ENTRY_SIZE;
|
||||
} else {
|
||||
std::memcpy(entry->chunk, data, count);
|
||||
outChunkPos = count;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
os::io::Library::v_size ChunkedBuffer::writeToEntryFrom(ChunkEntry* entry,
|
||||
os::io::Library::v_size inChunkPos,
|
||||
const void *data,
|
||||
os::io::Library::v_size count,
|
||||
os::io::Library::v_size& outChunkPos) {
|
||||
os::io::Library::v_size spaceLeft = CHUNK_ENTRY_SIZE - inChunkPos;
|
||||
if(count >= spaceLeft){
|
||||
std::memcpy(&((p_char8) entry->chunk)[inChunkPos], data, spaceLeft);
|
||||
outChunkPos = 0;
|
||||
return spaceLeft;
|
||||
} else {
|
||||
std::memcpy(&((p_char8) entry->chunk)[inChunkPos], data, count);
|
||||
outChunkPos = inChunkPos + count;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkedBuffer::ChunkEntry* ChunkedBuffer::getChunkForPosition(ChunkEntry* fromChunk,
|
||||
os::io::Library::v_size pos,
|
||||
os::io::Library::v_size& outChunkPos) {
|
||||
|
||||
os::io::Library::v_size segIndex = pos >> CHUNK_ENTRY_SIZE_INDEX_SHIFT;
|
||||
outChunkPos = pos - (segIndex << CHUNK_ENTRY_SIZE_INDEX_SHIFT);
|
||||
|
||||
auto curr = fromChunk;
|
||||
|
||||
for(os::io::Library::v_size i = 0; i < segIndex; i++){
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return curr;
|
||||
|
||||
}
|
||||
|
||||
os::io::Library::v_size ChunkedBuffer::write(const void *data, os::io::Library::v_size count){
|
||||
|
||||
if(count <= 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(m_lastEntry == nullptr){
|
||||
obtainNewEntry();
|
||||
}
|
||||
|
||||
ChunkEntry* entry = m_lastEntry;
|
||||
os::io::Library::v_size pos = 0;
|
||||
|
||||
pos += writeToEntryFrom(entry, m_chunkPos, data, count, m_chunkPos);
|
||||
|
||||
if(m_chunkPos == 0){
|
||||
entry = obtainNewEntry();
|
||||
}
|
||||
|
||||
while (pos < count) {
|
||||
|
||||
pos += writeToEntry(entry, &((p_char8) data)[pos], count - pos, m_chunkPos);
|
||||
|
||||
if(m_chunkPos == 0){
|
||||
entry = obtainNewEntry();
|
||||
}
|
||||
}
|
||||
|
||||
m_size += pos; // pos == count
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
os::io::Library::v_size ChunkedBuffer::readSubstring(void *buffer,
|
||||
os::io::Library::v_size pos,
|
||||
os::io::Library::v_size count) {
|
||||
|
||||
if(pos < 0 || pos >= m_size){
|
||||
return 0;
|
||||
}
|
||||
|
||||
os::io::Library::v_size countToRead;
|
||||
if(pos + count > m_size){
|
||||
countToRead = m_size - pos;
|
||||
} else {
|
||||
countToRead = count;
|
||||
}
|
||||
|
||||
os::io::Library::v_size firstChunkPos;
|
||||
auto firstChunk = getChunkForPosition(m_firstEntry, pos, firstChunkPos);
|
||||
|
||||
os::io::Library::v_size lastChunkPos;
|
||||
auto lastChunk = getChunkForPosition(firstChunk, firstChunkPos + countToRead, lastChunkPos);
|
||||
|
||||
os::io::Library::v_size bufferPos = 0;
|
||||
|
||||
if(firstChunk != lastChunk){
|
||||
|
||||
os::io::Library::v_size countToCopy = CHUNK_ENTRY_SIZE - firstChunkPos;
|
||||
std::memcpy(buffer, &((p_char8)firstChunk->chunk)[firstChunkPos], countToCopy);
|
||||
bufferPos += countToCopy;
|
||||
|
||||
auto curr = firstChunk->next;
|
||||
|
||||
while (curr != lastChunk) {
|
||||
std::memcpy(&((p_char8)buffer)[bufferPos], curr->chunk, CHUNK_ENTRY_SIZE);
|
||||
bufferPos += CHUNK_ENTRY_SIZE;
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
std::memcpy(&((p_char8)buffer)[bufferPos], lastChunk->chunk, lastChunkPos);
|
||||
|
||||
} else {
|
||||
os::io::Library::v_size countToCopy = lastChunkPos - firstChunkPos;
|
||||
std::memcpy(buffer, &((p_char8)firstChunk->chunk)[firstChunkPos], countToCopy);
|
||||
}
|
||||
|
||||
return countToRead;
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::base::String> ChunkedBuffer::getSubstring(os::io::Library::v_size pos,
|
||||
os::io::Library::v_size count){
|
||||
auto str = oatpp::base::String::createShared((v_int32) count);
|
||||
readSubstring(str->getData(), pos, count);
|
||||
return str;
|
||||
}
|
||||
|
||||
bool ChunkedBuffer::flushToStream(const std::shared_ptr<OutputStream>& stream){
|
||||
os::io::Library::v_size pos = m_size;
|
||||
auto curr = m_firstEntry;
|
||||
while (pos > 0) {
|
||||
if(pos > CHUNK_ENTRY_SIZE) {
|
||||
auto res = stream->write(curr->chunk, CHUNK_ENTRY_SIZE);
|
||||
if(res != CHUNK_ENTRY_SIZE) {
|
||||
return false;
|
||||
}
|
||||
pos -= res;
|
||||
} else {
|
||||
auto res = stream->write(curr->chunk, pos);
|
||||
if(res != pos) {
|
||||
return false;
|
||||
}
|
||||
pos -= res;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<ChunkedBuffer::Chunks> ChunkedBuffer::getChunks() {
|
||||
auto chunks = Chunks::createShared();
|
||||
auto curr = m_firstEntry;
|
||||
v_int32 count = 0;
|
||||
while (curr != nullptr) {
|
||||
if(curr->next != nullptr){
|
||||
chunks->pushBack(Chunk::createShared(curr->chunk, CHUNK_ENTRY_SIZE));
|
||||
} else {
|
||||
chunks->pushBack(Chunk::createShared(curr->chunk, m_size - CHUNK_ENTRY_SIZE * count));
|
||||
}
|
||||
++count;
|
||||
curr = curr->next;
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
os::io::Library::v_size ChunkedBuffer::getSize(){
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void ChunkedBuffer::clear(){
|
||||
|
||||
ChunkEntry* curr = m_firstEntry;
|
||||
while (curr != nullptr) {
|
||||
ChunkEntry* next = curr->next;
|
||||
freeEntry(curr);
|
||||
curr = next;
|
||||
}
|
||||
|
||||
m_size = 0;
|
||||
m_chunkPos = 0;
|
||||
m_firstEntry = nullptr;
|
||||
m_lastEntry = nullptr;
|
||||
|
||||
}
|
||||
|
||||
}}}
|
167
core/src/data/stream/ChunkedBuffer.hpp
Normal file
167
core/src/data/stream/ChunkedBuffer.hpp
Normal file
@ -0,0 +1,167 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_stream_ChunkedBuffer_hpp
|
||||
#define oatpp_data_stream_ChunkedBuffer_hpp
|
||||
|
||||
#include "./Stream.hpp"
|
||||
|
||||
#include "../../collection/LinkedList.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
class ChunkedBuffer : public oatpp::base::Controllable, public OutputStream {
|
||||
public:
|
||||
OBJECT_POOL(ChunkedBuffer_Pool, ChunkedBuffer, 32)
|
||||
SHARED_OBJECT_POOL(Shared_ChunkedBuffer_Pool, ChunkedBuffer, 32)
|
||||
public:
|
||||
|
||||
static const char* const CHUNK_POOL_NAME;
|
||||
|
||||
static const os::io::Library::v_size CHUNK_ENTRY_SIZE_INDEX_SHIFT;
|
||||
static const os::io::Library::v_size CHUNK_ENTRY_SIZE;
|
||||
static const os::io::Library::v_size CHUNK_CHUNK_SIZE;
|
||||
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getSegemntPool(){
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool pool(CHUNK_POOL_NAME,
|
||||
(v_int32) CHUNK_ENTRY_SIZE,
|
||||
(v_int32) CHUNK_CHUNK_SIZE);
|
||||
return pool;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class ChunkEntry {
|
||||
public:
|
||||
OBJECT_POOL(ChunkedBuffer_ChunkEntry_Pool, ChunkEntry, 32)
|
||||
public:
|
||||
|
||||
ChunkEntry(void* pChunk, ChunkEntry* pNext)
|
||||
: chunk(pChunk)
|
||||
, next(pNext)
|
||||
{}
|
||||
|
||||
~ChunkEntry(){
|
||||
}
|
||||
|
||||
void* chunk;
|
||||
ChunkEntry* next;
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
class Chunk : public oatpp::base::Controllable {
|
||||
public:
|
||||
OBJECT_POOL(ChunkedBuffer_Chunk_Pool, Chunk, 32)
|
||||
SHARED_OBJECT_POOL(Shared_ChunkedBuffer_Chunk_Pool, Chunk, 32)
|
||||
public:
|
||||
|
||||
Chunk(void* pData, os::io::Library::v_size pSize)
|
||||
: data(pData)
|
||||
, size(pSize)
|
||||
{}
|
||||
|
||||
static std::shared_ptr<Chunk> createShared(void* data, os::io::Library::v_size size){
|
||||
return Shared_ChunkedBuffer_Chunk_Pool::allocateShared(data, size);
|
||||
}
|
||||
|
||||
const void* data;
|
||||
const os::io::Library::v_size size;
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
typedef oatpp::collection::LinkedList<std::shared_ptr<Chunk>> Chunks;
|
||||
private:
|
||||
|
||||
os::io::Library::v_size m_size;
|
||||
os::io::Library::v_size m_chunkPos;
|
||||
ChunkEntry* m_firstEntry;
|
||||
ChunkEntry* m_lastEntry;
|
||||
|
||||
private:
|
||||
|
||||
ChunkEntry* obtainNewEntry();
|
||||
void freeEntry(ChunkEntry* entry);
|
||||
|
||||
os::io::Library::v_size writeToEntry(ChunkEntry* entry,
|
||||
const void *data,
|
||||
os::io::Library::v_size count,
|
||||
os::io::Library::v_size& outChunkPos);
|
||||
|
||||
os::io::Library::v_size writeToEntryFrom(ChunkEntry* entry,
|
||||
os::io::Library::v_size inChunkPos,
|
||||
const void *data,
|
||||
os::io::Library::v_size count,
|
||||
os::io::Library::v_size& outChunkPos);
|
||||
|
||||
ChunkEntry* getChunkForPosition(ChunkEntry* fromChunk,
|
||||
os::io::Library::v_size pos,
|
||||
os::io::Library::v_size& outChunkPos);
|
||||
|
||||
public:
|
||||
|
||||
ChunkedBuffer()
|
||||
: m_size(0)
|
||||
, m_chunkPos(0)
|
||||
, m_firstEntry(nullptr)
|
||||
, m_lastEntry(nullptr)
|
||||
{}
|
||||
|
||||
~ChunkedBuffer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static std::shared_ptr<ChunkedBuffer> createShared(){
|
||||
return Shared_ChunkedBuffer_Pool::allocateShared();
|
||||
}
|
||||
|
||||
os::io::Library::v_size write(const void *data, os::io::Library::v_size count) override;
|
||||
|
||||
os::io::Library::v_size readSubstring(void *buffer,
|
||||
os::io::Library::v_size pos,
|
||||
os::io::Library::v_size count);
|
||||
|
||||
std::shared_ptr<oatpp::base::String> getSubstring(os::io::Library::v_size pos,
|
||||
os::io::Library::v_size count);
|
||||
|
||||
std::shared_ptr<oatpp::base::String> toString() {
|
||||
return getSubstring(0, m_size);
|
||||
}
|
||||
|
||||
bool flushToStream(const std::shared_ptr<OutputStream>& stream);
|
||||
|
||||
std::shared_ptr<Chunks> getChunks();
|
||||
|
||||
os::io::Library::v_size getSize();
|
||||
void clear();
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_data_stream_ChunkedBuffer_hpp */
|
25
core/src/data/stream/Delegate.cpp
Normal file
25
core/src/data/stream/Delegate.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Delegate.hpp"
|
44
core/src/data/stream/Delegate.hpp
Normal file
44
core/src/data/stream/Delegate.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_stream_Delegate_hpp
|
||||
#define oatpp_data_stream_Delegate_hpp
|
||||
|
||||
#include "./Stream.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
class WriterDelegate {
|
||||
public:
|
||||
virtual os::io::Library::v_size writeToStream(const std::shared_ptr<OutputStream>& stream) = 0;
|
||||
};
|
||||
|
||||
class ReaderDelegate {
|
||||
public:
|
||||
virtual os::io::Library::v_size readFromStream(const std::shared_ptr<InputStream>& stream) = 0;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_data_stream_Delegate_hpp */
|
135
core/src/data/stream/Stream.cpp
Normal file
135
core/src/data/stream/Stream.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Stream.hpp"
|
||||
#include "../../utils/ConversionUtils.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
os::io::Library::v_size OutputStream::writeAsString(v_int32 value){
|
||||
v_char8 a[100];
|
||||
v_int32 size = utils::conversion::int32ToCharSequence(value, &a[0]);
|
||||
if(size > 0){
|
||||
return write(&a[0], size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
os::io::Library::v_size OutputStream::writeAsString(v_int64 value){
|
||||
v_char8 a[100];
|
||||
v_int32 size = utils::conversion::int64ToCharSequence(value, &a[0]);
|
||||
if(size > 0){
|
||||
return write(&a[0], size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
os::io::Library::v_size OutputStream::writeAsString(v_float32 value){
|
||||
v_char8 a[100];
|
||||
v_int32 size = utils::conversion::float32ToCharSequence(value, &a[0]);
|
||||
if(size > 0){
|
||||
return write(&a[0], size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
os::io::Library::v_size OutputStream::writeAsString(v_float64 value){
|
||||
v_char8 a[100];
|
||||
v_int32 size = utils::conversion::float64ToCharSequence(value, &a[0]);
|
||||
if(size > 0){
|
||||
return write(&a[0], size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
os::io::Library::v_size OutputStream::writeAsString(bool value) {
|
||||
if(value){
|
||||
return write("true", 4);
|
||||
} else {
|
||||
return write("false", 5);
|
||||
}
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator <<
|
||||
(const std::shared_ptr<OutputStream>& s, const base::String::SharedWrapper& str) {
|
||||
s->write(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator <<
|
||||
(const std::shared_ptr<OutputStream>& s, const char* str) {
|
||||
s->write(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_int32 value) {
|
||||
s->writeAsString(value);
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_int64 value) {
|
||||
s->writeAsString(value);
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_float32 value) {
|
||||
s->writeAsString(value);
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_float64 value) {
|
||||
s->writeAsString(value);
|
||||
return s;
|
||||
}
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, bool value) {
|
||||
if(value) {
|
||||
s->OutputStream::write("true");
|
||||
} else {
|
||||
s->OutputStream::write("false");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void transfer(const std::shared_ptr<InputStream>& fromStream,
|
||||
const std::shared_ptr<OutputStream>& toStream,
|
||||
oatpp::os::io::Library::v_size transferSize,
|
||||
void* buffer,
|
||||
oatpp::os::io::Library::v_size bufferSize) {
|
||||
|
||||
while (transferSize > 0) {
|
||||
oatpp::os::io::Library::v_size desiredReadCount = transferSize;
|
||||
if(desiredReadCount > bufferSize){
|
||||
desiredReadCount = bufferSize;
|
||||
}
|
||||
auto readCount = fromStream->read(buffer, desiredReadCount);
|
||||
toStream->write(buffer, readCount);
|
||||
transferSize -= readCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}
|
128
core/src/data/stream/Stream.hpp
Normal file
128
core/src/data/stream/Stream.hpp
Normal file
@ -0,0 +1,128 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_Stream
|
||||
#define oatpp_data_Stream
|
||||
|
||||
#include "../../base/memory/ObjectPool.hpp"
|
||||
|
||||
#include "../../base/String.hpp"
|
||||
|
||||
#include "../../os/io/Library.hpp"
|
||||
|
||||
#include "../../base/SharedWrapper.hpp"
|
||||
#include "../../base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
class OutputStream {
|
||||
public:
|
||||
|
||||
virtual os::io::Library::v_size write(const void *data, os::io::Library::v_size count) = 0;
|
||||
|
||||
os::io::Library::v_size write(const char* data){
|
||||
return write((p_char8)data, std::strlen(data));
|
||||
}
|
||||
|
||||
os::io::Library::v_size write(const oatpp::base::SharedWrapper<oatpp::base::String>& str){
|
||||
return write(str->getData(), str->getSize());
|
||||
}
|
||||
|
||||
os::io::Library::v_size writeChar(v_char8 c){
|
||||
return write(&c, 1);
|
||||
}
|
||||
|
||||
os::io::Library::v_size writeAsString(v_int32 value);
|
||||
os::io::Library::v_size writeAsString(v_int64 value);
|
||||
os::io::Library::v_size writeAsString(v_float32 value);
|
||||
os::io::Library::v_size writeAsString(v_float64 value);
|
||||
os::io::Library::v_size writeAsString(bool value);
|
||||
|
||||
};
|
||||
|
||||
class InputStream {
|
||||
public:
|
||||
virtual os::io::Library::v_size read(void *data, os::io::Library::v_size count) = 0;
|
||||
};
|
||||
|
||||
class IOStream : public InputStream, public OutputStream {
|
||||
public:
|
||||
typedef os::io::Library::v_size v_size;
|
||||
};
|
||||
|
||||
class CompoundIOStream : public oatpp::base::Controllable, public IOStream {
|
||||
public:
|
||||
OBJECT_POOL(CompoundIOStream_Pool, CompoundIOStream, 32);
|
||||
SHARED_OBJECT_POOL(Shared_CompoundIOStream_Pool, CompoundIOStream, 32);
|
||||
private:
|
||||
std::shared_ptr<OutputStream> m_outputStream;
|
||||
std::shared_ptr<InputStream> m_inputStream;
|
||||
public:
|
||||
CompoundIOStream(const std::shared_ptr<OutputStream>& outputStream,
|
||||
const std::shared_ptr<InputStream>& inputStream)
|
||||
: m_outputStream(outputStream)
|
||||
, m_inputStream(inputStream)
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<CompoundIOStream> createShared(const std::shared_ptr<OutputStream>& outputStream,
|
||||
const std::shared_ptr<InputStream>& inputStream){
|
||||
return Shared_CompoundIOStream_Pool::allocateShared(outputStream, inputStream);
|
||||
}
|
||||
|
||||
os::io::Library::v_size write(const void *data, os::io::Library::v_size count) override {
|
||||
return m_outputStream->write(data, count);
|
||||
}
|
||||
|
||||
os::io::Library::v_size read(void *data, os::io::Library::v_size count) override {
|
||||
return m_inputStream->read(data, count);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator <<
|
||||
(const std::shared_ptr<OutputStream>& s, const base::String::SharedWrapper& str);
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator <<
|
||||
(const std::shared_ptr<OutputStream>& s, const char* str);
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_int32 value);
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_int64 value);
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_float32 value);
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, v_float64 value);
|
||||
|
||||
const std::shared_ptr<OutputStream>& operator << (const std::shared_ptr<OutputStream>& s, bool value);
|
||||
|
||||
void transfer(const std::shared_ptr<InputStream>& fromStream,
|
||||
const std::shared_ptr<OutputStream>& toStream,
|
||||
oatpp::os::io::Library::v_size transferSize,
|
||||
void* buffer,
|
||||
oatpp::os::io::Library::v_size bufferSize);
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* defined(_data_Stream) */
|
165
core/src/data/stream/StreamBufferedProxy.cpp
Normal file
165
core/src/data/stream/StreamBufferedProxy.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "StreamBufferedProxy.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
os::io::Library::v_size OutputStreamBufferedProxy::write(const void *data, os::io::Library::v_size count) {
|
||||
if(m_pos == 0){
|
||||
|
||||
v_bufferSize spaceLeft = m_bufferSize - m_posEnd;
|
||||
if(spaceLeft > count){
|
||||
memcpy(&m_buffer[m_posEnd], data, count);
|
||||
m_posEnd += (v_bufferSize) count;
|
||||
return count;
|
||||
}
|
||||
|
||||
if(m_posEnd == 0) {
|
||||
return m_outputStream->write(data, count);
|
||||
}
|
||||
|
||||
if(spaceLeft > 0){
|
||||
memcpy(&m_buffer[m_posEnd], data, spaceLeft);
|
||||
m_posEnd = m_bufferSize;
|
||||
}
|
||||
|
||||
os::io::Library::v_size writeResult = m_outputStream->write(m_buffer, m_bufferSize);
|
||||
|
||||
if(writeResult == m_bufferSize){
|
||||
m_posEnd = 0;
|
||||
os::io::Library::v_size bigResult = write(&((p_char8) data)[spaceLeft], count - spaceLeft);
|
||||
if(bigResult > 0) {
|
||||
return bigResult + spaceLeft;
|
||||
} else {
|
||||
return spaceLeft;
|
||||
}
|
||||
}
|
||||
|
||||
if(writeResult > 0){
|
||||
m_pos += (v_bufferSize) writeResult;
|
||||
}
|
||||
|
||||
return spaceLeft;
|
||||
|
||||
} else {
|
||||
auto amount = m_posEnd - m_pos;
|
||||
if(amount > 0){
|
||||
os::io::Library::v_size result = m_outputStream->write(&m_buffer[m_pos], amount);
|
||||
if(result == amount){
|
||||
m_pos = 0;
|
||||
m_posEnd = 0;
|
||||
return write(data, count);
|
||||
} else if(result > 0){
|
||||
m_pos += (v_bufferSize) result;
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
m_pos = 0;
|
||||
m_posEnd = 0;
|
||||
return write(data, count);
|
||||
}
|
||||
}
|
||||
|
||||
os::io::Library::v_size OutputStreamBufferedProxy::flush() {
|
||||
auto amount = m_posEnd - m_pos;
|
||||
if(amount > 0){
|
||||
os::io::Library::v_size result = m_outputStream->write(&m_buffer[m_pos], amount);
|
||||
if(result == amount){
|
||||
m_pos = 0;
|
||||
m_posEnd = 0;
|
||||
} else if(result > 0){
|
||||
m_pos += (v_bufferSize) result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
os::io::Library::v_size InputStreamBufferedProxy::read(void *data, os::io::Library::v_size count) {
|
||||
|
||||
if (m_pos == 0 && m_posEnd == 0) {
|
||||
|
||||
if(count > m_bufferSize){
|
||||
//if(m_hasError){
|
||||
// errno = m_errno;
|
||||
// return -1;
|
||||
//}
|
||||
return m_inputStream->read(data, count);
|
||||
} else {
|
||||
//if(m_hasError){
|
||||
// errno = m_errno;
|
||||
// return -1;
|
||||
//}
|
||||
m_posEnd = (v_bufferSize) m_inputStream->read(m_buffer, m_bufferSize);
|
||||
v_bufferSize result;
|
||||
if(m_posEnd > count){
|
||||
result = (v_bufferSize) count;
|
||||
m_pos = result;
|
||||
} else {
|
||||
result = m_posEnd;
|
||||
m_posEnd = 0;
|
||||
m_pos = 0;
|
||||
if(result < 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
std::memcpy(data, m_buffer, result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
v_bufferSize result = m_posEnd - m_pos;
|
||||
if(count > result){
|
||||
|
||||
std::memcpy(data, &m_buffer[m_pos], result);
|
||||
|
||||
m_pos = 0;
|
||||
m_posEnd = 0;
|
||||
os::io::Library::v_size bigResult = read(&((p_char8) data) [result], count - result);
|
||||
if(bigResult > 0){
|
||||
return bigResult + result;
|
||||
} else {
|
||||
//m_hasError = true;
|
||||
//m_errno = errno;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} else {
|
||||
std::memcpy(data, &m_buffer[m_pos], count);
|
||||
m_pos += (v_bufferSize) count;
|
||||
if(m_pos == m_posEnd){
|
||||
m_pos = 0;
|
||||
m_posEnd = 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}
|
177
core/src/data/stream/StreamBufferedProxy.hpp
Normal file
177
core/src/data/stream/StreamBufferedProxy.hpp
Normal file
@ -0,0 +1,177 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_stream_StreamBufferedProxy_hpp
|
||||
#define oatpp_data_stream_StreamBufferedProxy_hpp
|
||||
|
||||
#include "./Stream.hpp"
|
||||
#include "../buffer/IOBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
class OutputStreamBufferedProxy : public oatpp::base::Controllable, public OutputStream {
|
||||
public:
|
||||
OBJECT_POOL(OutputStreamBufferedProxy_Pool, OutputStreamBufferedProxy, 32)
|
||||
SHARED_OBJECT_POOL(Shared_OutputStreamBufferedProxy_Pool, OutputStreamBufferedProxy, 32)
|
||||
public:
|
||||
typedef v_int32 v_bufferSize;
|
||||
private:
|
||||
std::shared_ptr<OutputStream> m_outputStream;
|
||||
std::shared_ptr<oatpp::data::buffer::IOBuffer> m_bufferPtr;
|
||||
p_char8 m_buffer;
|
||||
v_bufferSize m_bufferSize;
|
||||
v_bufferSize m_pos;
|
||||
v_bufferSize m_posEnd;
|
||||
public:
|
||||
OutputStreamBufferedProxy(const std::shared_ptr<OutputStream>& outputStream,
|
||||
const std::shared_ptr<oatpp::data::buffer::IOBuffer>& bufferPtr,
|
||||
p_char8 buffer,
|
||||
v_bufferSize bufferSize)
|
||||
: m_outputStream(outputStream)
|
||||
, m_bufferPtr(bufferPtr)
|
||||
, m_buffer(buffer)
|
||||
, m_bufferSize(bufferSize)
|
||||
, m_pos(0)
|
||||
, m_posEnd(0)
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<OutputStreamBufferedProxy> createShared(const std::shared_ptr<OutputStream>& outputStream,
|
||||
const std::shared_ptr<oatpp::data::buffer::IOBuffer>& buffer)
|
||||
{
|
||||
return Shared_OutputStreamBufferedProxy_Pool::allocateShared(outputStream,
|
||||
buffer,
|
||||
(p_char8) buffer->getData(),
|
||||
buffer->getSize());
|
||||
}
|
||||
|
||||
static std::shared_ptr<OutputStreamBufferedProxy> createShared(const std::shared_ptr<OutputStream>& outputStream,
|
||||
p_char8 buffer,
|
||||
v_bufferSize bufferSize)
|
||||
{
|
||||
return Shared_OutputStreamBufferedProxy_Pool::allocateShared(outputStream,
|
||||
nullptr,
|
||||
buffer,
|
||||
bufferSize);
|
||||
}
|
||||
|
||||
os::io::Library::v_size write(const void *data, os::io::Library::v_size count) override;
|
||||
os::io::Library::v_size flush();
|
||||
|
||||
void setBufferPosition(v_bufferSize pos, v_bufferSize posEnd){
|
||||
m_pos = pos;
|
||||
m_posEnd = posEnd;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class InputStreamBufferedProxy : public oatpp::base::Controllable, public InputStream {
|
||||
public:
|
||||
OBJECT_POOL(InputStreamBufferedProxy_Pool, InputStreamBufferedProxy, 32)
|
||||
SHARED_OBJECT_POOL(Shared_InputStreamBufferedProxy_Pool, InputStreamBufferedProxy, 32)
|
||||
public:
|
||||
typedef v_int32 v_bufferSize;
|
||||
protected:
|
||||
std::shared_ptr<InputStream> m_inputStream;
|
||||
std::shared_ptr<oatpp::data::buffer::IOBuffer> m_bufferPtr;
|
||||
p_char8 m_buffer;
|
||||
v_bufferSize m_bufferSize;
|
||||
v_bufferSize m_pos;
|
||||
v_bufferSize m_posEnd;
|
||||
public:
|
||||
InputStreamBufferedProxy(const std::shared_ptr<InputStream>& inputStream,
|
||||
const std::shared_ptr<oatpp::data::buffer::IOBuffer>& bufferPtr,
|
||||
p_char8 buffer,
|
||||
v_bufferSize bufferSize,
|
||||
v_bufferSize positionStart,
|
||||
v_bufferSize positionEnd)
|
||||
: m_inputStream(inputStream)
|
||||
, m_bufferPtr(bufferPtr)
|
||||
, m_buffer(buffer)
|
||||
, m_bufferSize(bufferSize)
|
||||
, m_pos(positionStart)
|
||||
, m_posEnd(positionEnd)
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<InputStreamBufferedProxy> createShared(const std::shared_ptr<InputStream>& inputStream,
|
||||
const std::shared_ptr<oatpp::data::buffer::IOBuffer>& buffer)
|
||||
{
|
||||
return Shared_InputStreamBufferedProxy_Pool::allocateShared(inputStream,
|
||||
buffer,
|
||||
(p_char8) buffer->getData(),
|
||||
buffer->getSize(),
|
||||
0, 0);
|
||||
}
|
||||
|
||||
static std::shared_ptr<InputStreamBufferedProxy> createShared(const std::shared_ptr<InputStream>& inputStream,
|
||||
const std::shared_ptr<oatpp::data::buffer::IOBuffer>& buffer,
|
||||
v_bufferSize positionStart,
|
||||
v_bufferSize positionEnd)
|
||||
{
|
||||
return Shared_InputStreamBufferedProxy_Pool::allocateShared(inputStream,
|
||||
buffer,
|
||||
(p_char8) buffer->getData(),
|
||||
buffer->getSize(),
|
||||
positionStart,
|
||||
positionEnd);
|
||||
}
|
||||
|
||||
static std::shared_ptr<InputStreamBufferedProxy> createShared(const std::shared_ptr<InputStream>& inputStream,
|
||||
p_char8 buffer,
|
||||
v_bufferSize bufferSize)
|
||||
{
|
||||
return Shared_InputStreamBufferedProxy_Pool::allocateShared(inputStream,
|
||||
nullptr,
|
||||
buffer,
|
||||
bufferSize,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
static std::shared_ptr<InputStreamBufferedProxy> createShared(const std::shared_ptr<InputStream>& inputStream,
|
||||
p_char8 buffer,
|
||||
v_bufferSize bufferSize,
|
||||
v_bufferSize positionStart,
|
||||
v_bufferSize positionEnd)
|
||||
{
|
||||
return Shared_InputStreamBufferedProxy_Pool::allocateShared(inputStream,
|
||||
nullptr,
|
||||
buffer,
|
||||
bufferSize,
|
||||
positionStart,
|
||||
positionEnd);
|
||||
}
|
||||
|
||||
os::io::Library::v_size read(void *data, os::io::Library::v_size count) override;
|
||||
|
||||
void setBufferPosition(v_bufferSize pos, v_bufferSize posEnd){
|
||||
m_pos = pos;
|
||||
m_posEnd = posEnd;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_data_stream_StreamBufferedProxy_hpp */
|
498
core/src/macro/basic.hpp
Normal file
498
core/src/macro/basic.hpp
Normal file
@ -0,0 +1,498 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_macro_ForEach_hpp
|
||||
#define oatpp_macro_ForEach_hpp
|
||||
|
||||
#define OATPP_MACRO_FOREACH_EXAMPLE_FUNC(INDEX, COUNT, X) \
|
||||
ENV::log("macro", "param: %d/%d: '%s'", INDEX, COUNT, #X);
|
||||
|
||||
#define OATPP_MACRO_FOREACH_EXAMPLE(...) OATPP_MACRO_FOREACH(OATPP_MACRO_FOREACH_EXAMPLE_FUNC, (__VA_ARGS__))
|
||||
|
||||
#define OATPP_MACRO__NUM_ARGS(X100, X99, X98, X97, X96, X95, X94, X93, X92, X91, X90, X89, X88, X87, X86, X85, X84, X83, X82, X81, X80, X79, X78, X77, X76, X75, X74, X73, X72, X71, X70, X69, X68, X67, X66, X65, X64, X63, X62, X61, X60, X59, X58, X57, X56, X55, X54, X53, X52, X51, X50, X49, X48, X47, X46, X45, X44, X43, X42, X41, X40, X39, X38, X37, X36, X35, X34, X33, X32, X31, X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, X16, X15, X14, X13, X12, X11, X10, X9, X8, X7, X6, X5, X4, X3, X2, X1, N, ...) N
|
||||
|
||||
#define OATPP_MACRO_NUM_ARGS(...) OATPP_MACRO__NUM_ARGS(__VA_ARGS__, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
|
||||
#define OATPP_MACRO_HAS_ARGS_ARR(...) OATPP_MACRO__NUM_ARGS(__VA_ARGS__, true, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
|
||||
|
||||
|
||||
#define OATPP_MACRO_CONCAT(X,Y) OATPP_MACRO_CONCAT(X,Y)
|
||||
#define OATPP_MACRO_CONCAT2(X,Y) X##Y
|
||||
#define OATPP_MACRO_CONCAT_2 OATPP_MACRO_CONCAT
|
||||
#define OATPP_MACRO_CONCAT_3(X,Y,Z) OATPP_MACRO_CONCAT(X,OATPP_MACRO_CONCAT(Y,Z))
|
||||
|
||||
#define OATPP_MACRO_STR(X) #X
|
||||
|
||||
#define OATPP_MACRO_HAS_ARGS(...) OATPP_MACRO_HAS_ARGS_ARR(L, ##__VA_ARGS__)
|
||||
|
||||
#define OATPP_MACRO_EXPAND(X) X
|
||||
#define OATPP_MACRO_FIRSTARG(X, ...) X
|
||||
#define OATPP_MACRO_FIRSTARG_STR(X, ...) #X
|
||||
#define OATPP_MACRO_RESTARGS(X, ...) (__VA_ARGS__)
|
||||
|
||||
#define OATPP_MACRO_FIRSTARG_EXPAND(X, ...) OATPP_MACRO_FIRSTARG X
|
||||
|
||||
/////////
|
||||
|
||||
#define OATPP_MACRO_MACRO_OR_EMPTY_0(MACRO, LIST)
|
||||
#define OATPP_MACRO_MACRO_OR_EMPTY_1(MACRO, LIST) MACRO
|
||||
|
||||
#define OATPP_MACRO_MACRO_OR_EMPTY_(X, MACRO, LIST) \
|
||||
OATPP_MACRO_MACRO_OR_EMPTY_##X(MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_MACRO_OR_EMPTY__(X, MACRO, LIST) \
|
||||
OATPP_MACRO_MACRO_OR_EMPTY_(X, MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_MACRO_OR_EMPTY___(MACRO, LIST) \
|
||||
OATPP_MACRO_MACRO_OR_EMPTY__(OATPP_MACRO_HAS_ARGS LIST, MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_MACRO_OR_EMPTY(MACRO, ...) \
|
||||
OATPP_MACRO_MACRO_OR_EMPTY___(MACRO, (__VA_ARGS__))
|
||||
|
||||
//////////
|
||||
|
||||
#define OATPP_MACRO_FOREACH_OR_EMPTY_0(MACRO, LIST)
|
||||
#define OATPP_MACRO_FOREACH_OR_EMPTY_1(MACRO, LIST) OATPP_MACRO_FOREACH(MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_OR_EMPTY_(X, MACRO, LIST) \
|
||||
OATPP_MACRO_FOREACH_OR_EMPTY_##X(MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_OR_EMPTY__(X, MACRO, LIST) \
|
||||
OATPP_MACRO_FOREACH_OR_EMPTY_(X, MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_OR_EMPTY___(MACRO, LIST) \
|
||||
OATPP_MACRO_FOREACH_OR_EMPTY__(OATPP_MACRO_HAS_ARGS LIST, MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_OR_EMPTY(MACRO, LIST) \
|
||||
OATPP_MACRO_FOREACH_OR_EMPTY___(MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_FIRST_AND_REST_(FIRST_MACRO, FIRST_ARG, MACRO, LIST) \
|
||||
FIRST_MACRO(0, 0, FIRST_ARG) OATPP_MACRO_FOREACH_OR_EMPTY(MACRO, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_FIRST_AND_REST(FIRST_MACRO, MACRO, LIST) \
|
||||
OATPP_MACRO_FOREACH_FIRST_AND_REST_(FIRST_MACRO, OATPP_MACRO_FIRSTARG LIST, MACRO, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
/////////
|
||||
|
||||
#define OATPP_MACRO_FOREACH(MACRO, LIST) OATPP_MACRO_FOREACH_(OATPP_MACRO_NUM_ARGS LIST, MACRO, LIST)
|
||||
#define OATPP_MACRO_FOREACH_(N, M, LIST) OATPP_MACRO_FOREACH__(N, M, LIST)
|
||||
#define OATPP_MACRO_FOREACH__(N, M, LIST) OATPP_MACRO_FOREACH_##N(N, M, LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_CALL(INDEX, COUNT, MACRO, PARAM) MACRO(INDEX, COUNT, PARAM)
|
||||
#define OATPP_MACRO_FOREACH_1(N, M, LIST) OATPP_MACRO_FOREACH_CALL(N - 1, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))
|
||||
|
||||
#define OATPP_MACRO_FOREACH_2(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 2, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_1(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_3(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 3, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_2(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_4(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 4, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_3(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_5(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 5, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_4(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_6(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 6, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_5(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_7(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 7, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_6(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_8(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 8, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_7(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_9(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 9, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_8(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_10(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 10, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_9(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_11(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 11, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_10(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_12(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 12, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_11(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_13(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 13, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_12(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_14(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 14, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_13(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_15(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 15, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_14(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_16(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 16, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_15(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_17(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 17, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_16(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_18(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 18, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_17(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_19(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 19, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_18(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_20(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 20, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_19(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_21(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 21, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_20(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_22(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 22, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_21(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_23(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 23, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_22(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_24(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 24, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_23(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_25(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 25, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_24(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_26(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 26, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_25(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_27(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 27, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_26(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_28(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 28, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_27(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_29(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 29, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_28(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_30(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 30, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_29(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_31(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 31, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_30(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_32(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 32, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_31(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_33(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 33, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_32(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_34(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 34, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_33(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_35(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 35, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_34(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_36(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 36, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_35(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_37(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 37, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_36(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_38(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 38, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_37(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_39(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 39, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_38(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_40(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 40, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_39(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_41(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 41, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_40(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_42(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 42, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_41(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_43(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 43, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_42(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_44(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 44, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_43(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_45(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 45, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_44(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_46(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 46, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_45(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_47(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 47, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_46(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_48(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 48, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_47(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_49(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 49, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_48(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_50(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 50, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_49(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_51(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 51, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_50(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_52(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 52, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_51(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_53(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 53, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_52(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_54(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 54, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_53(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_55(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 55, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_54(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_56(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 56, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_55(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_57(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 57, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_56(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_58(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 58, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_57(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_59(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 59, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_58(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_60(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 60, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_59(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_61(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 61, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_60(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_62(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 62, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_61(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_63(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 63, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_62(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_64(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 64, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_63(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_65(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 65, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_64(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_66(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 66, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_65(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_67(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 67, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_66(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_68(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 68, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_67(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_69(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 69, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_68(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_70(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 70, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_69(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_71(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 71, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_70(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_72(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 72, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_71(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_73(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 73, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_72(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_74(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 74, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_73(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_75(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 75, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_74(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_76(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 76, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_75(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_77(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 77, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_76(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_78(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 78, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_77(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_79(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 79, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_78(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_80(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 80, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_79(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_81(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 81, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_80(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_82(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 82, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_81(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_83(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 83, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_82(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_84(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 84, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_83(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_85(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 85, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_84(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_86(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 86, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_85(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_87(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 87, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_86(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_88(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 88, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_87(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_89(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 89, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_88(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_90(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 90, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_89(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_91(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 91, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_90(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_92(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 92, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_91(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_93(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 93, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_92(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_94(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 94, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_93(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_95(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 95, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_94(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_96(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 96, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_95(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_97(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 97, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_96(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_98(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 98, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_97(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
#define OATPP_MACRO_FOREACH_99(N, M, LIST) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_FOREACH_CALL(N - 99, N, M, OATPP_MACRO_FIRSTARG_EXPAND(LIST))) \
|
||||
OATPP_MACRO_FOREACH_98(N, M, OATPP_MACRO_RESTARGS LIST)
|
||||
|
||||
|
||||
#endif /* oatpp_macro_ForEach_hpp */
|
35
core/src/macro/codegen.hpp
Normal file
35
core/src/macro/codegen.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 codegen_hpp
|
||||
#define codegen_hpp
|
||||
|
||||
#include "./basic.hpp"
|
||||
|
||||
#define OATPP_MACRO_CODEGEN_EXPAND(X) OATPP_MACRO_STR(X)
|
||||
|
||||
#define OATPP_CODEGEN_BEGIN(NAME) OATPP_MACRO_CODEGEN_EXPAND(OATPP_MACRO_CONCAT2(zzz_macro_define_, NAME##_.hpp))
|
||||
#define OATPP_CODEGEN_END(NAME) OATPP_MACRO_CODEGEN_EXPAND(OATPP_MACRO_CONCAT2(zzz_macro_undef_, NAME##_.hpp))
|
||||
|
||||
#endif /* codegen_hpp */
|
72
core/src/macro/component.hpp
Normal file
72
core/src/macro/component.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_macro_component_hpp
|
||||
#define oatpp_macro_component_hpp
|
||||
|
||||
#include "../base/Environment.hpp"
|
||||
#include "./basic.hpp"
|
||||
|
||||
#define OATPP_MACRO_GET_COMPONENT_0(TYPE, LIST) \
|
||||
(*((TYPE*) oatpp::base::Environment::getComponent(typeid(TYPE).name())))
|
||||
|
||||
#define OATPP_MACRO_GET_COMPONENT_1(TYPE, LIST) \
|
||||
(*((TYPE*) oatpp::base::Environment::getComponent(typeid(TYPE).name(), OATPP_MACRO_FIRSTARG LIST)))
|
||||
|
||||
#define OATPP_MACRO_GET_COMPONENT_(X, TYPE, LIST) \
|
||||
OATPP_MACRO_GET_COMPONENT_##X(TYPE, LIST)
|
||||
|
||||
#define OATPP_MACRO_GET_COMPONENT__(X, TYPE, LIST) \
|
||||
OATPP_MACRO_GET_COMPONENT_(X, TYPE, LIST)
|
||||
|
||||
#define OATPP_MACRO_GET_COMPONENT___(TYPE, LIST) \
|
||||
OATPP_MACRO_GET_COMPONENT__(OATPP_MACRO_HAS_ARGS LIST, TYPE, LIST)
|
||||
|
||||
#define OATPP_GET_COMPONENT(TYPE, ...) \
|
||||
OATPP_MACRO_GET_COMPONENT___(TYPE, (__VA_ARGS__))
|
||||
|
||||
|
||||
#define OATPP_MACRO_COMPONENT_0(TYPE, NAME, LIST) \
|
||||
TYPE& NAME = (*((TYPE*) oatpp::base::Environment::getComponent(typeid(TYPE).name())))
|
||||
|
||||
#define OATPP_MACRO_COMPONENT_1(TYPE, NAME, LIST) \
|
||||
TYPE& NAME = (*((TYPE*) oatpp::base::Environment::getComponent(typeid(TYPE).name(), OATPP_MACRO_FIRSTARG LIST)))
|
||||
|
||||
#define OATPP_MACRO_COMPONENT_(X, TYPE, NAME, LIST) \
|
||||
OATPP_MACRO_COMPONENT_##X(TYPE, NAME, LIST)
|
||||
|
||||
#define OATPP_MACRO_COMPONENT__(X, TYPE, NAME, LIST) \
|
||||
OATPP_MACRO_COMPONENT_(X, TYPE, NAME, LIST)
|
||||
|
||||
#define OATPP_MACRO_COMPONENT___(TYPE, NAME, LIST) \
|
||||
OATPP_MACRO_COMPONENT__(OATPP_MACRO_HAS_ARGS LIST, TYPE, NAME, LIST)
|
||||
|
||||
#define OATPP_COMPONENT(TYPE, NAME, ...) \
|
||||
OATPP_MACRO_COMPONENT___(TYPE, NAME, (__VA_ARGS__))
|
||||
|
||||
|
||||
#define OATPP_CREATE_COMPONENT(TYPE, NAME) \
|
||||
oatpp::base::Environment::Component<TYPE> NAME = oatpp::base::Environment::Component<TYPE>
|
||||
|
||||
#endif /* oatpp_macro_component_hpp */
|
45
core/src/os/io/Library.cpp
Normal file
45
core/src/os/io/Library.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Library.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
namespace oatpp { namespace os { namespace io {
|
||||
|
||||
v_int32 Library::handle_close(v_handle handle){
|
||||
return close(handle);
|
||||
}
|
||||
|
||||
Library::v_size Library::handle_read(v_handle handle, void *buf, v_size count){
|
||||
return read(handle, buf, count);
|
||||
}
|
||||
|
||||
Library::v_size Library::handle_write(v_handle handle, const void *buf, v_size count){
|
||||
return write(handle, buf, count);
|
||||
}
|
||||
|
||||
}}}
|
47
core/src/os/io/Library.hpp
Normal file
47
core/src/os/io/Library.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_os_io_Library_hpp
|
||||
#define oatpp_os_io_Library_hpp
|
||||
|
||||
#include "../../base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace os { namespace io {
|
||||
|
||||
class Library{
|
||||
public:
|
||||
typedef v_int32 v_handle;
|
||||
typedef ssize_t v_size;
|
||||
public:
|
||||
|
||||
static v_int32 handle_close(v_handle handle);
|
||||
|
||||
static v_size handle_read(v_handle handle, void *buf, v_size count);
|
||||
static v_size handle_write(v_handle handle, const void *buf, v_size count);
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_os_io_Library_hpp */
|
577
core/src/parser/ParsingCaret.cpp
Normal file
577
core/src/parser/ParsingCaret.cpp
Normal file
@ -0,0 +1,577 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ParsingCaret.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace oatpp { namespace parser {
|
||||
|
||||
const char* const ParsingCaret::ERROR_INVALID_INTEGER = "ERROR_INVALID_INTEGER";
|
||||
const char* const ParsingCaret::ERROR_INVALID_FLOAT = "ERROR_INVALID_FLOAT";
|
||||
const char* const ParsingCaret::ERROR_INVALID_BOOLEAN = "ERROR_INVALID_BOOLEAN";
|
||||
const char* const ParsingCaret::ERROR_NO_OPEN_TAG = "ERROR_NO_OPEN_TAG";
|
||||
const char* const ParsingCaret::ERROR_NO_CLOSE_TAG = "ERROR_NO_CLOSE_TAG";
|
||||
const char* const ParsingCaret::ERROR_NAME_EXPECTED = "ERROR_NAME_EXPECTED";
|
||||
|
||||
ParsingCaret::ParsingCaret(const char* text)
|
||||
: m_data((p_char8)text)
|
||||
, m_size((v_int32) std::strlen(text))
|
||||
, m_pos(0)
|
||||
, m_error(nullptr)
|
||||
{}
|
||||
|
||||
ParsingCaret::ParsingCaret(p_char8 parseData, v_int32 dataSize)
|
||||
: m_data(parseData)
|
||||
, m_size(dataSize)
|
||||
, m_pos(0)
|
||||
, m_error(nullptr)
|
||||
{}
|
||||
|
||||
ParsingCaret::ParsingCaret(const std::shared_ptr<base::String>& str)
|
||||
: m_data(str->getData())
|
||||
, m_size(str->getSize())
|
||||
, m_pos(0)
|
||||
, m_error(nullptr)
|
||||
{}
|
||||
|
||||
std::shared_ptr<ParsingCaret> ParsingCaret::createShared(const char* text){
|
||||
return std::shared_ptr<ParsingCaret>(new ParsingCaret(text));
|
||||
}
|
||||
|
||||
std::shared_ptr<ParsingCaret> ParsingCaret::createShared(p_char8 parseData, v_int32 dataSize){
|
||||
return std::shared_ptr<ParsingCaret>(new ParsingCaret(parseData, dataSize));
|
||||
}
|
||||
|
||||
std::shared_ptr<ParsingCaret> ParsingCaret::createShared(const std::shared_ptr<base::String>& str){
|
||||
return std::shared_ptr<ParsingCaret>(new ParsingCaret(str->getData(), str->getSize()));
|
||||
}
|
||||
|
||||
ParsingCaret::~ParsingCaret(){
|
||||
}
|
||||
|
||||
p_char8 ParsingCaret::getData(){
|
||||
return m_data;
|
||||
}
|
||||
|
||||
p_char8 ParsingCaret::getCurrData(){
|
||||
return &m_data[m_pos];
|
||||
}
|
||||
|
||||
v_int32 ParsingCaret::getSize(){
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void ParsingCaret::setPosition(v_int32 position){
|
||||
m_pos = position;
|
||||
}
|
||||
|
||||
v_int32 ParsingCaret::getPosition(){
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
void ParsingCaret::setError(const char* error){
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
const char* ParsingCaret::getError(){
|
||||
return m_error;
|
||||
}
|
||||
|
||||
bool ParsingCaret::hasError(){
|
||||
return m_error != nullptr;
|
||||
}
|
||||
|
||||
void ParsingCaret::clearError(){
|
||||
m_error = nullptr;
|
||||
}
|
||||
|
||||
void ParsingCaret::inc(){
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
void ParsingCaret::inc(v_int32 amount){
|
||||
m_pos+= amount;
|
||||
}
|
||||
|
||||
bool ParsingCaret::findNotBlankChar(){
|
||||
|
||||
while(m_pos < m_size){
|
||||
v_char8 a = m_data[m_pos];
|
||||
if(a != ' ' && a != '\t' && a != '\n' && a != '\r' && a != '\f')
|
||||
return true;
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::findNotSpaceChar(){
|
||||
|
||||
while(m_pos < m_size){
|
||||
if(m_data[m_pos] != ' ')
|
||||
return true;
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::findChar(v_char8 c){
|
||||
|
||||
while(m_pos < m_size){
|
||||
if(m_data[m_pos] == c)
|
||||
return true;
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::findCharNotFromSet(const char* set){
|
||||
return findCharNotFromSet((p_char8)set, (v_int32) std::strlen(set));
|
||||
}
|
||||
|
||||
bool ParsingCaret::findCharNotFromSet(p_char8 set, v_int32 setSize){
|
||||
|
||||
while(m_pos < m_size){
|
||||
if(notAtCharFromSet(set, setSize)){
|
||||
return true;
|
||||
}
|
||||
m_pos++;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
v_int32 ParsingCaret::findCharFromSet(const char* set){
|
||||
return findCharFromSet((p_char8) set, (v_int32) std::strlen(set));
|
||||
}
|
||||
|
||||
v_int32 ParsingCaret::findCharFromSet(p_char8 set, v_int32 setSize){
|
||||
|
||||
while(m_pos < m_size){
|
||||
|
||||
v_char8 a = m_data[m_pos];
|
||||
|
||||
for(v_int32 i = 0; i < setSize; i++){
|
||||
if(set[i] == a)
|
||||
return a;
|
||||
}
|
||||
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
bool ParsingCaret::findNextLine(){
|
||||
|
||||
bool nlFound = false;
|
||||
|
||||
while(m_pos < m_size){
|
||||
|
||||
if(nlFound){
|
||||
|
||||
if(m_data[m_pos] != '\n' && m_data[m_pos] != '\r'){
|
||||
return true;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
if(m_data[m_pos] == '\n' || m_data[m_pos] == '\r'){
|
||||
nlFound = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool ParsingCaret::findRN() {
|
||||
|
||||
while(m_pos < m_size){
|
||||
if(m_data[m_pos] == '\r'){
|
||||
if(m_pos + 1 < m_size && m_data[m_pos + 1] == '\n'){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::skipRN() {
|
||||
if(m_pos + 1 < m_size && m_data[m_pos] == '\r' && m_data[m_pos + 1] == '\n'){
|
||||
m_pos += 2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::isAtRN() {
|
||||
return (m_pos + 1 < m_size && m_data[m_pos] == '\r' && m_data[m_pos + 1] == '\n');
|
||||
}
|
||||
|
||||
v_int32 ParsingCaret::parseInteger(bool allowNegative){
|
||||
|
||||
bool negative = m_data[m_pos] == '-';
|
||||
|
||||
if(negative){
|
||||
|
||||
if(!allowNegative){
|
||||
m_error = ERROR_INVALID_INTEGER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inc();
|
||||
if(findNotSpaceChar() == false){
|
||||
m_error = ERROR_INVALID_INTEGER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
v_int32 ipos = m_pos;
|
||||
|
||||
while(m_pos < m_size && m_data[m_pos] >= '0' && m_data[m_pos] <= '9'){
|
||||
m_pos ++;
|
||||
}
|
||||
|
||||
v_int32 len = m_pos - ipos;
|
||||
|
||||
if(len > 0){
|
||||
|
||||
auto str = base::String::createShared(&m_data[ipos], len, true);
|
||||
v_int32 result = atoi((const char*)str->getData());
|
||||
|
||||
if(negative){
|
||||
result = - result;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}else{
|
||||
m_error = ERROR_INVALID_INTEGER;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
v_int32 ParsingCaret::parseInt32(){
|
||||
char* end;
|
||||
char* start = (char*)&m_data[m_pos];
|
||||
v_int32 result = (v_float32) std::strtol(start, &end, 10);
|
||||
if(start == end){
|
||||
m_error = ERROR_INVALID_INTEGER;
|
||||
}
|
||||
m_pos = (v_int32)((v_int64) end - (v_int64) m_data);
|
||||
return result;
|
||||
}
|
||||
|
||||
v_int64 ParsingCaret::parseInt64(){
|
||||
char* end;
|
||||
char* start = (char*)&m_data[m_pos];
|
||||
v_int64 result = std::strtol(start, &end, 10);
|
||||
if(start == end){
|
||||
m_error = ERROR_INVALID_INTEGER;
|
||||
}
|
||||
m_pos = (v_int32)((v_int64) end - (v_int64) m_data);
|
||||
return result;
|
||||
}
|
||||
|
||||
v_float32 ParsingCaret::parseFloat32(){
|
||||
char* end;
|
||||
char* start = (char*)&m_data[m_pos];
|
||||
v_float32 result = std::strtof(start , &end);
|
||||
if(start == end){
|
||||
m_error = ERROR_INVALID_FLOAT;
|
||||
}
|
||||
m_pos = (v_int32)((v_int64) end - (v_int64) m_data);
|
||||
return result;
|
||||
}
|
||||
|
||||
v_float64 ParsingCaret::parseFloat64(){
|
||||
char* end;
|
||||
char* start = (char*)&m_data[m_pos];
|
||||
v_float64 result = std::strtod(start , &end);
|
||||
if(start == end){
|
||||
m_error = ERROR_INVALID_FLOAT;
|
||||
}
|
||||
m_pos = (v_int32)((v_int64) end - (v_int64) m_data);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ParsingCaret::parseBoolean(const char* trueText, const char* falseText){
|
||||
if(proceedIfFollowsText(trueText)){
|
||||
return true;
|
||||
} else if(proceedIfFollowsText(falseText)){
|
||||
return false;
|
||||
}
|
||||
setError(ERROR_INVALID_BOOLEAN);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::proceedIfFollowsText(const char* text){
|
||||
return proceedIfFollowsText((p_char8)text, (v_int32) std::strlen(text));
|
||||
}
|
||||
|
||||
bool ParsingCaret::proceedIfFollowsText(p_char8 text, v_int32 textSize){
|
||||
|
||||
if(textSize <= m_size - m_pos){
|
||||
|
||||
for(v_int32 i = 0; i < textSize; i++){
|
||||
|
||||
if(text[i] != m_data[m_pos + i]){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_pos = m_pos + textSize;
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ParsingCaret::proceedIfFollowsTextNCS(const char* text){
|
||||
return proceedIfFollowsTextNCS((p_char8)text, (v_int32) std::strlen(text));
|
||||
}
|
||||
|
||||
bool ParsingCaret::proceedIfFollowsTextNCS(p_char8 text, v_int32 textSize){
|
||||
|
||||
if(textSize <= m_size - m_pos){
|
||||
|
||||
for(v_int32 i = 0; i < textSize; i++){
|
||||
|
||||
v_char8 c1 = text[i];
|
||||
v_char8 c2 = m_data[m_pos + i];
|
||||
|
||||
if(c1 >= 'a' && c1 <= 'z'){
|
||||
c1 = 'A' + c1 - 'a';
|
||||
}
|
||||
|
||||
if(c2 >= 'a' && c2 <= 'z'){
|
||||
c2 = 'A' + c2 - 'a';
|
||||
}
|
||||
|
||||
if(c1 != c2){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_pos = m_pos + textSize;
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ParsingCaret::proceedIfFollowsWord(const char* text){
|
||||
return proceedIfFollowsWord((p_char8)text, (v_int32) std::strlen(text));
|
||||
}
|
||||
|
||||
bool ParsingCaret::proceedIfFollowsWord(p_char8 text, v_int32 textSize){
|
||||
|
||||
if(textSize <= m_size - m_pos){
|
||||
|
||||
for(v_int32 i = 0; i < textSize; i++){
|
||||
|
||||
if(text[i] != m_data[m_pos + i]){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
v_char8 a = m_data[m_pos + textSize];
|
||||
|
||||
if(!(a >= '0' && a <= '9') && !(a >= 'a' && a <= 'z') &&
|
||||
!(a >= 'A' && a <= 'Z') && a != '_'){
|
||||
|
||||
m_pos = m_pos + textSize;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<base::String> ParsingCaret::parseStringEnclosed(char openChar, char closeChar, char escapeChar, bool saveAsOwnData){
|
||||
|
||||
if(m_data[m_pos] == openChar){
|
||||
|
||||
m_pos++;
|
||||
|
||||
v_int32 ipos = m_pos;
|
||||
|
||||
while(canContinue()){
|
||||
|
||||
if(m_data[m_pos] == escapeChar){
|
||||
m_pos++;
|
||||
}else if(m_data[m_pos] == closeChar){
|
||||
std::shared_ptr<base::String> result = base::String::createShared(&m_data[ipos], m_pos - ipos, saveAsOwnData);
|
||||
m_pos++;
|
||||
return result;
|
||||
}
|
||||
|
||||
m_pos++;
|
||||
}
|
||||
|
||||
m_error = ERROR_NO_CLOSE_TAG;
|
||||
|
||||
}else{
|
||||
m_error = ERROR_NO_OPEN_TAG;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<base::String> ParsingCaret::parseName(bool saveAsOwnData){
|
||||
|
||||
v_int32 ipos = m_pos;
|
||||
while(m_pos < m_size){
|
||||
|
||||
v_char8 a = m_data[m_pos];
|
||||
|
||||
if( (a >= '0' && a <= '9')||
|
||||
(a >= 'a' && a <= 'z')||
|
||||
(a >= 'A' && a <= 'Z')||
|
||||
(a == '_')){
|
||||
m_pos ++;
|
||||
}else{
|
||||
|
||||
if(ipos < m_pos){
|
||||
return base::String::createShared(&m_data[ipos], m_pos - ipos, saveAsOwnData);
|
||||
}else{
|
||||
m_error = ERROR_NAME_EXPECTED;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(ipos < m_pos){
|
||||
return base::String::createShared(&m_data[ipos], m_pos - ipos, saveAsOwnData);
|
||||
}else{
|
||||
m_error = ERROR_NAME_EXPECTED;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::base::String> ParsingCaret::findTextFromList(const std::shared_ptr<oatpp::collection::LinkedList<std::shared_ptr<oatpp::base::String>>>& list){
|
||||
|
||||
while(m_pos < m_size){
|
||||
|
||||
auto currNode = list->getFirstNode();
|
||||
while(currNode != nullptr){
|
||||
auto str = currNode->getData();
|
||||
if(proceedIfFollowsText(str->getData(), str->getSize())){
|
||||
return str;
|
||||
}
|
||||
currNode = currNode->getNext();
|
||||
}
|
||||
|
||||
m_pos++;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
bool ParsingCaret::notAtCharFromSet(const char* set) const{
|
||||
return notAtCharFromSet((p_char8)set, (v_int32) std::strlen(set));
|
||||
}
|
||||
|
||||
bool ParsingCaret::notAtCharFromSet(p_char8 set, v_int32 setSize) const{
|
||||
|
||||
v_char8 a = m_data[m_pos];
|
||||
|
||||
for(v_int32 i = 0; i < setSize; i++){
|
||||
if(a == set[i]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool ParsingCaret::isAtChar(v_char8 c) const{
|
||||
return m_data[m_pos] == c;
|
||||
}
|
||||
|
||||
bool ParsingCaret::isAtBlankChar() const{
|
||||
v_char8 a = m_data[m_pos];
|
||||
return (a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\b' || a == '\f');
|
||||
}
|
||||
|
||||
bool ParsingCaret::isAtDigitChar() const{
|
||||
v_char8 a = m_data[m_pos];
|
||||
return (a >= '0' && a <= '9');
|
||||
}
|
||||
|
||||
bool ParsingCaret::canContinueAtChar(v_char8 c) const{
|
||||
return m_pos < m_size && m_error == 0 && m_data[m_pos] == c;
|
||||
}
|
||||
|
||||
bool ParsingCaret::canContinueAtChar(v_char8 c, v_int32 skipChars){
|
||||
|
||||
if(m_pos < m_size && m_error == 0 && m_data[m_pos] == c){
|
||||
m_pos = m_pos + skipChars;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParsingCaret::canContinue() const{
|
||||
return m_pos < m_size && m_error == 0;
|
||||
}
|
||||
|
||||
bool ParsingCaret::isEnd() const{
|
||||
return m_pos >= m_size;
|
||||
}
|
||||
|
||||
|
||||
}}
|
169
core/src/parser/ParsingCaret.hpp
Normal file
169
core/src/parser/ParsingCaret.hpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_parser_ParsingCaret_hpp
|
||||
#define oatpp_parser_ParsingCaret_hpp
|
||||
|
||||
#include "../collection/LinkedList.hpp"
|
||||
#include "../base/String.hpp"
|
||||
|
||||
namespace oatpp { namespace parser {
|
||||
|
||||
class ParsingCaret : public base::Controllable{
|
||||
public:
|
||||
static const char* const ERROR_INVALID_INTEGER;
|
||||
static const char* const ERROR_INVALID_FLOAT;
|
||||
static const char* const ERROR_INVALID_BOOLEAN;
|
||||
static const char* const ERROR_NO_OPEN_TAG;
|
||||
static const char* const ERROR_NO_CLOSE_TAG;
|
||||
static const char* const ERROR_NAME_EXPECTED;
|
||||
public:
|
||||
class Label {
|
||||
private:
|
||||
ParsingCaret& m_caret;
|
||||
v_int32 m_start;
|
||||
v_int32 m_end;
|
||||
public:
|
||||
|
||||
Label(ParsingCaret& caret)
|
||||
: m_caret(caret)
|
||||
, m_start(caret.m_pos)
|
||||
, m_end(-1)
|
||||
{}
|
||||
|
||||
void end(){
|
||||
m_end = m_caret.m_pos;
|
||||
}
|
||||
|
||||
p_char8 getData(){
|
||||
return &m_caret.m_data[m_start];
|
||||
}
|
||||
|
||||
v_int32 getSize(){
|
||||
return m_end - m_start;
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::base::String> toString(bool saveAsOwnData){
|
||||
v_int32 end = m_end;
|
||||
if(end == -1){
|
||||
end = m_caret.m_pos;
|
||||
}
|
||||
return oatpp::base::String::createShared(&m_caret.m_data[m_start], end - m_start, saveAsOwnData);
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::base::String> toString(){
|
||||
return toString(true);
|
||||
}
|
||||
|
||||
};
|
||||
private:
|
||||
p_char8 m_data;
|
||||
v_int32 m_size;
|
||||
v_int32 m_pos;
|
||||
const char* m_error;
|
||||
public:
|
||||
ParsingCaret(const char* text);
|
||||
ParsingCaret(p_char8 parseData, v_int32 dataSize);
|
||||
ParsingCaret(const std::shared_ptr<base::String>& str);
|
||||
public:
|
||||
|
||||
static std::shared_ptr<ParsingCaret> createShared(const char* text);
|
||||
static std::shared_ptr<ParsingCaret> createShared(p_char8 parseData, v_int32 dataSize);
|
||||
static std::shared_ptr<ParsingCaret> createShared(const std::shared_ptr<base::String>& str);
|
||||
|
||||
virtual ~ParsingCaret();
|
||||
|
||||
p_char8 getData();
|
||||
p_char8 getCurrData();
|
||||
v_int32 getSize();
|
||||
|
||||
void setPosition(v_int32 position);
|
||||
v_int32 getPosition();
|
||||
|
||||
void setError(const char* error);
|
||||
const char* getError();
|
||||
bool hasError();
|
||||
void clearError();
|
||||
|
||||
void inc();
|
||||
void inc(v_int32 amount);
|
||||
|
||||
bool findNotBlankChar(); // findCharNotFromSet(" \n\r\t");
|
||||
|
||||
bool findNotSpaceChar();
|
||||
bool findChar(v_char8 c);
|
||||
|
||||
bool findCharNotFromSet(const char* set);
|
||||
bool findCharNotFromSet(p_char8 set, v_int32 setSize);
|
||||
|
||||
v_int32 findCharFromSet(const char* set);
|
||||
v_int32 findCharFromSet(p_char8 set, v_int32 setSize);
|
||||
|
||||
bool findNextLine();
|
||||
bool findRN();
|
||||
bool skipRN();
|
||||
bool isAtRN();
|
||||
|
||||
v_int32 parseInteger(bool allowNegative); // Will setError if error
|
||||
|
||||
v_int32 parseInt32();
|
||||
v_int64 parseInt64();
|
||||
|
||||
v_float32 parseFloat32();
|
||||
v_float64 parseFloat64();
|
||||
|
||||
bool parseBoolean(const char* trueText, const char* falseText); // will setError if error
|
||||
|
||||
bool proceedIfFollowsText(const char* text); // not increases pos if false
|
||||
bool proceedIfFollowsText(p_char8 text, v_int32 textSize); // not increases pos if false
|
||||
|
||||
bool proceedIfFollowsTextNCS(const char* text); // NotCaseSensative
|
||||
bool proceedIfFollowsTextNCS(p_char8 text, v_int32 textSize); // not increases pos if false
|
||||
|
||||
bool proceedIfFollowsWord(const char* text); // not increases pos if false
|
||||
bool proceedIfFollowsWord(p_char8 text, v_int32 textSize); // not increases pos if false
|
||||
|
||||
std::shared_ptr<base::String> parseStringEnclosed(char openChar, char closeChar, char escapeChar, bool saveAsOwnData);
|
||||
std::shared_ptr<base::String> parseName(bool saveAsOwnData);
|
||||
|
||||
std::shared_ptr<base::String> findTextFromList(const std::shared_ptr<oatpp::collection::LinkedList<std::shared_ptr<base::String>>>& list);
|
||||
|
||||
bool notAtCharFromSet(const char* set) const;
|
||||
bool notAtCharFromSet(p_char8 set, v_int32 setSize) const;
|
||||
bool isAtChar(v_char8 c) const;
|
||||
bool isAtBlankChar() const;
|
||||
bool isAtDigitChar() const;
|
||||
bool canContinueAtChar(v_char8 c) const;
|
||||
bool canContinueAtChar(v_char8 c, v_int32 skipChars);
|
||||
|
||||
bool canContinue() const;
|
||||
bool isEnd() const;
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
|
||||
#endif /* oatpp_parser_ParsingCaret_hpp */
|
169
core/src/utils/ConversionUtils.cpp
Normal file
169
core/src/utils/ConversionUtils.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 "ConversionUtils.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace oatpp { namespace utils { namespace conversion {
|
||||
|
||||
v_int32 strToInt32(const char* str){
|
||||
char* end;
|
||||
return (v_int32) std::strtol(str, &end, 10);
|
||||
}
|
||||
|
||||
v_int32 strToInt32(const base::SharedWrapper<base::String>& str, bool& success){
|
||||
char* end;
|
||||
v_int32 result = (v_int32) std::strtol((const char*)str->getData(), &end, 10);
|
||||
success = (((v_int64)end - (v_int64)str->getData()) == str->getSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
v_int64 strToInt64(const char* str){
|
||||
char* end;
|
||||
return std::strtoll(str, &end, 10);
|
||||
}
|
||||
|
||||
v_int64 strToInt64(const base::SharedWrapper<base::String>& str, bool& success){
|
||||
char* end;
|
||||
v_int64 result = std::strtoll((const char*)str->getData(), &end, 10);
|
||||
success = (((v_int64)end - (v_int64)str->getData()) == str->getSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
v_int32 int32ToCharSequence(v_int32 value, p_char8 data){
|
||||
return sprintf((char*)data, "%d", value);
|
||||
}
|
||||
|
||||
v_int32 int64ToCharSequence(v_int64 value, p_char8 data){
|
||||
return sprintf((char*)data, "%lld", value);
|
||||
}
|
||||
|
||||
base::SharedWrapper<base::String> int32ToStr(v_int32 value){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = int32ToCharSequence(value, &buff[0]);
|
||||
if(size > 0){
|
||||
return base::String::createShared(&buff[0], size, true);
|
||||
}
|
||||
return base::SharedWrapper<base::String>::empty();
|
||||
}
|
||||
|
||||
base::SharedWrapper<base::String> int64ToStr(v_int64 value){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = int64ToCharSequence(value, &buff[0]);
|
||||
if(size > 0){
|
||||
return base::String::createShared(&buff[0], size, true);
|
||||
}
|
||||
return base::SharedWrapper<base::String>::empty();
|
||||
}
|
||||
|
||||
std::string int32ToStdStr(v_int32 value){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = int32ToCharSequence(value, &buff[0]);
|
||||
if(size > 0){
|
||||
return std::string((const char*)buff, size);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string int64ToStdStr(v_int64 value){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = int64ToCharSequence(value, &buff[0]);
|
||||
if(size > 0){
|
||||
return std::string((const char*)buff, size);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v_float32 strToFloat32(const char* str){
|
||||
char* end;
|
||||
return std::strtof(str, &end);
|
||||
}
|
||||
|
||||
v_float32 strToFloat32(const base::SharedWrapper<base::String>& str, bool& success) {
|
||||
char* end;
|
||||
v_float32 result = std::strtof((const char*)str->getData(), &end);
|
||||
success = (((v_int64)end - (v_int64)str->getData()) == str->getSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
v_float64 strToFloat64(const char* str){
|
||||
char* end;
|
||||
return std::strtod(str, &end);
|
||||
}
|
||||
|
||||
v_float64 strToFloat64(const base::SharedWrapper<base::String>& str, bool& success) {
|
||||
char* end;
|
||||
v_float64 result = std::strtod((const char*)str->getData(), &end);
|
||||
success = (((v_int64)end - (v_int64)str->getData()) == str->getSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
v_int32 float32ToCharSequence(v_float32 value, p_char8 data){
|
||||
return sprintf((char*)data, "%f", value);
|
||||
}
|
||||
|
||||
v_int32 float64ToCharSequence(v_float64 value, p_char8 data){
|
||||
return sprintf((char*)data, "%f", value);
|
||||
}
|
||||
|
||||
base::SharedWrapper<base::String> float32ToStr(v_float32 value){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = float32ToCharSequence(value, &buff[0]);
|
||||
if(size > 0){
|
||||
return base::String::createShared(&buff[0], size, true);
|
||||
}
|
||||
return base::SharedWrapper<base::String>::empty();
|
||||
}
|
||||
|
||||
base::SharedWrapper<base::String> float64ToStr(v_float64 value){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = float32ToCharSequence(value, &buff[0]);
|
||||
if(size > 0){
|
||||
return base::String::createShared(&buff[0], size, true);
|
||||
}
|
||||
return base::SharedWrapper<base::String>::empty();
|
||||
}
|
||||
|
||||
base::SharedWrapper<base::String> boolToStr(bool value) {
|
||||
if(value){
|
||||
return base::String::createShared((p_char8)"true", 4, false);
|
||||
} else {
|
||||
return base::String::createShared((p_char8)"false", 5, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool strToBool(const base::SharedWrapper<base::String>& str, bool& success) {
|
||||
if(str->equals((p_char8)"true", 4)){
|
||||
success = true;
|
||||
return true;
|
||||
} else if(str->equals((p_char8)"false", 5)){
|
||||
success = true;
|
||||
return false;
|
||||
}
|
||||
success = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
}}}
|
84
core/src/utils/ConversionUtils.hpp
Normal file
84
core/src/utils/ConversionUtils.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_utils_ConversionUtils_hpp
|
||||
#define oatpp_utils_ConversionUtils_hpp
|
||||
|
||||
#include "../base/String.hpp"
|
||||
|
||||
#include "../base/SharedWrapper.hpp"
|
||||
#include "../base/Controllable.hpp"
|
||||
#include "../base/Environment.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace oatpp { namespace utils { namespace conversion {
|
||||
|
||||
v_int32 strToInt32(const char* str);
|
||||
v_int32 strToInt32(const base::SharedWrapper<base::String>& str, bool& success);
|
||||
v_int64 strToInt64(const char* str);
|
||||
v_int64 strToInt64(const base::SharedWrapper<base::String>& str, bool& success);
|
||||
|
||||
v_int32 int32ToCharSequence(v_int32 value, p_char8 data);
|
||||
v_int32 int64ToCharSequence(v_int64 value, p_char8 data);
|
||||
|
||||
base::SharedWrapper<base::String> int32ToStr(v_int32 value);
|
||||
base::SharedWrapper<base::String> int64ToStr(v_int64 value);
|
||||
|
||||
std::string int32ToStdStr(v_int32 value);
|
||||
std::string int64ToStdStr(v_int64 value);
|
||||
|
||||
template<typename T>
|
||||
v_int32 primitiveToCharSequence(T value, p_char8 data, const char* pattern){
|
||||
return sprintf((char*)data, pattern, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
base::SharedWrapper<base::String> primitiveToStr(T value, const char* pattern){
|
||||
v_char8 buff [100];
|
||||
v_int32 size = primitiveToCharSequence(value, &buff[0], pattern);
|
||||
if(size > 0){
|
||||
return base::String::createShared(&buff[0], size, true);
|
||||
}
|
||||
return base::SharedWrapper<base::String>::empty();
|
||||
}
|
||||
|
||||
v_float32 strToFloat32(const char* str);
|
||||
v_float32 strToFloat32(const base::SharedWrapper<base::String>& str, bool& success);
|
||||
v_float64 strToFloat64(const char* str);
|
||||
v_float64 strToFloat64(const base::SharedWrapper<base::String>& str, bool& success);
|
||||
|
||||
v_int32 float32ToCharSequence(v_float32 value, p_char8 data);
|
||||
v_int32 float64ToCharSequence(v_float64 value, p_char8 data);
|
||||
|
||||
base::SharedWrapper<base::String> float32ToStr(v_float32 value);
|
||||
base::SharedWrapper<base::String> float64ToStr(v_float64 value);
|
||||
|
||||
base::SharedWrapper<base::String> boolToStr(bool value);
|
||||
bool strToBool(const base::SharedWrapper<base::String>& str, bool& success);
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_utils_ConversionUtils_hpp */
|
57
core/test/Checker.cpp
Normal file
57
core/test/Checker.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Checker.hpp"
|
||||
|
||||
namespace oatpp { namespace test {
|
||||
|
||||
v_int64 PerformanceChecker::getMicroTickCount(){
|
||||
std::chrono::microseconds ms = std::chrono::duration_cast<std::chrono::microseconds>
|
||||
(std::chrono::system_clock::now().time_since_epoch());
|
||||
return ms.count();
|
||||
}
|
||||
|
||||
|
||||
ThreadLocalObjectsChecker::ThreadLocalObjectsChecker(const char* tag)
|
||||
: m_tag(tag)
|
||||
, m_objectsCount(oatpp::base::Environment::getThreadLocalObjectsCount())
|
||||
, m_objectsCreated(oatpp::base::Environment::getThreadLocalObjectsCreated())
|
||||
{
|
||||
}
|
||||
|
||||
ThreadLocalObjectsChecker::~ThreadLocalObjectsChecker(){
|
||||
|
||||
v_counter leakingObjects = base::Environment::getThreadLocalObjectsCount() - m_objectsCount;
|
||||
v_counter objectsCreatedPerTest = base::Environment::getThreadLocalObjectsCreated() - m_objectsCreated;
|
||||
|
||||
if(leakingObjects == 0){
|
||||
OATPP_LOGE(m_tag, "OK:\n created(obj): %d", objectsCreatedPerTest);
|
||||
}else{
|
||||
OATPP_LOGE(m_tag, "FAILED, leakingObjects = %d", leakingObjects);
|
||||
OATPP_ASSERT(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}
|
74
core/test/Checker.hpp
Normal file
74
core/test/Checker.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_Checker_hpp
|
||||
#define oatpp_test_Checker_hpp
|
||||
|
||||
#include "../src/base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace test {
|
||||
|
||||
class PerformanceChecker {
|
||||
public:
|
||||
static v_int64 getMicroTickCount();
|
||||
private:
|
||||
const char* m_tag;
|
||||
v_int64 m_ticks;
|
||||
public:
|
||||
PerformanceChecker(const char* tag)
|
||||
: m_tag(tag)
|
||||
, m_ticks(getMicroTickCount())
|
||||
{}
|
||||
|
||||
~PerformanceChecker(){
|
||||
v_int64 elapsedTicks = getMicroTickCount() - m_ticks;
|
||||
OATPP_LOGD(m_tag, "%d(micro)", elapsedTicks);
|
||||
}
|
||||
|
||||
v_int64 getElapsedTicks(){
|
||||
return getMicroTickCount() - m_ticks;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ThreadLocalObjectsChecker {
|
||||
private:
|
||||
class MemoryPoolData {
|
||||
public:
|
||||
const char* name;
|
||||
v_int64 size;
|
||||
v_int64 objectsCount;
|
||||
};
|
||||
private:
|
||||
const char* m_tag;
|
||||
v_counter m_objectsCount;
|
||||
v_counter m_objectsCreated;
|
||||
public:
|
||||
ThreadLocalObjectsChecker(const char* tag);
|
||||
~ThreadLocalObjectsChecker();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* Checker_hpp */
|
92
core/test/UnitTest.cpp
Normal file
92
core/test/UnitTest.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "UnitTest.hpp"
|
||||
|
||||
#include "../src/base/memory/MemoryPool.hpp" // delete
|
||||
#include "../src/base/Controllable.hpp" // delete
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace oatpp { namespace test {
|
||||
|
||||
v_int64 UnitTest::getTickCount(){
|
||||
std::chrono::microseconds ms = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()
|
||||
);
|
||||
|
||||
return ms.count();
|
||||
|
||||
}
|
||||
|
||||
bool UnitTest::run(v_int32 times) {
|
||||
|
||||
OATPP_LOGD(TAG, "START...");
|
||||
|
||||
v_counter objectsCount = base::Environment::getObjectsCount();
|
||||
v_counter objectsCreated = base::Environment::getObjectsCreated();
|
||||
|
||||
v_int64 ticks = getTickCount();
|
||||
|
||||
bool result = true;
|
||||
|
||||
for(v_int32 i = 0; i < times; i++){
|
||||
result = onRun();
|
||||
}
|
||||
|
||||
v_int64 millis = getTickCount() - ticks;
|
||||
|
||||
v_counter leakingObjects = base::Environment::getObjectsCount() - objectsCount;
|
||||
v_counter objectsCreatedPerTest = base::Environment::getObjectsCreated() - objectsCreated;
|
||||
|
||||
if(leakingObjects == 0 && result == true){
|
||||
OATPP_LOGD(TAG, "FINISHED - success");
|
||||
OATPP_LOGD(TAG, "%d(micro), %d(objs)\n", millis, objectsCreatedPerTest);
|
||||
}else{
|
||||
result = false;
|
||||
OATPP_LOGD(TAG, "FINISHED - failed, leakingObjects = %d", leakingObjects);
|
||||
|
||||
auto POOLS = oatpp::base::memory::MemoryPool::POOLS;
|
||||
auto it = POOLS.begin();
|
||||
while (it != POOLS.end()) {
|
||||
auto pool = it->second;
|
||||
OATPP_LOGD("Pool", "name: '%s' [%d(objs)]", pool->getName().c_str(), pool->getObjectsCount());
|
||||
it ++;
|
||||
}
|
||||
/*
|
||||
leakingObjects = base::Environment::getObjectsCount() - objectsCount;
|
||||
base::Environment::log(TAG,
|
||||
"FINISHED - failed, leakingObjects = %d",
|
||||
leakingObjects);
|
||||
*/
|
||||
}
|
||||
|
||||
OATPP_LOGD("test", "Pools count=%d", oatpp::base::memory::MemoryPool::POOLS.size());
|
||||
|
||||
OATPP_ASSERT(result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}}
|
66
core/test/UnitTest.hpp
Normal file
66
core/test/UnitTest.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 __testbase__UnitTest__
|
||||
#define __testbase__UnitTest__
|
||||
|
||||
#include "../src/base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace test {
|
||||
|
||||
class UnitTest{
|
||||
protected:
|
||||
const char* const TAG;
|
||||
public:
|
||||
|
||||
UnitTest(const char* testTAG)
|
||||
: TAG(testTAG)
|
||||
{}
|
||||
|
||||
virtual ~UnitTest(){
|
||||
}
|
||||
|
||||
v_int64 getTickCount();
|
||||
|
||||
bool run(v_int32 times);
|
||||
|
||||
bool run(){
|
||||
return run(1);
|
||||
}
|
||||
|
||||
virtual bool onRun() = 0;
|
||||
|
||||
template<class T>
|
||||
static void runTest(v_int32 times){
|
||||
T test;
|
||||
test.run(times);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#define OATPP_RUN_TEST(TEST) oatpp::test::UnitTest::runTest<TEST>(1)
|
||||
|
||||
}}
|
||||
|
||||
#endif /* defined(__testbase__UnitTest__) */
|
299
core/test/base/RegRuleTest.cpp
Normal file
299
core/test/base/RegRuleTest.cpp
Normal file
@ -0,0 +1,299 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "../../src/data/mapping/type/Primitive.hpp"
|
||||
#include "../../src/base/String.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
class BaseClass : public oatpp::base::Controllable {
|
||||
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::base::String String;
|
||||
|
||||
template<typename T>
|
||||
using SharedWrapper = oatpp::base::SharedWrapper<T>;
|
||||
|
||||
template<typename T>
|
||||
using PolymorphicWrapper = oatpp::data::mapping::type::PolymorphicWrapper<T>;
|
||||
|
||||
template<typename T>
|
||||
using TypeSharedWrapper = oatpp::data::mapping::type::SharedWrapper<T, oatpp::data::mapping::type::__class::Void>;
|
||||
|
||||
typedef oatpp::data::mapping::type::VariantWrapper VariantWrapper;
|
||||
|
||||
typedef oatpp::data::mapping::type::StringSharedWrapper StringSharedWrapper;
|
||||
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;
|
||||
|
||||
template <class SharedWrapperBC, class SharedWrapperCC, class BC, class CC>
|
||||
void checkSharedWrapper(){
|
||||
{
|
||||
SharedWrapperBC reg1(new BC);
|
||||
SharedWrapperBC reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
SharedWrapperBC reg4(BC::template create1<SharedWrapperBC>());
|
||||
SharedWrapperBC reg5(BC::template create2<SharedWrapperBC>());
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapperBC reg1 = new BC;
|
||||
SharedWrapperBC reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
SharedWrapperBC reg4 = BC::template create1<SharedWrapperBC>();
|
||||
SharedWrapperBC reg5 = BC::template create2<SharedWrapperBC>();
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapperBC reg1 = new BC;
|
||||
SharedWrapperBC reg2;
|
||||
reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg3;
|
||||
reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
SharedWrapperBC reg4;
|
||||
reg4 = BC::template create1<SharedWrapperBC>();
|
||||
SharedWrapperBC reg5;
|
||||
reg5 = BC::template create2<SharedWrapperBC>();
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
{
|
||||
SharedWrapperCC reg1(new CC);
|
||||
SharedWrapperBC reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg4(CC::template create1<SharedWrapperCC>());
|
||||
SharedWrapperBC reg5(CC::template create2<SharedWrapperCC>());
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapperCC reg1 = new CC;
|
||||
SharedWrapperBC reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg4 = CC::template create1<SharedWrapperCC>();
|
||||
SharedWrapperBC reg5 = CC::template create2<SharedWrapperCC>();
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapperCC reg1 = new CC;
|
||||
SharedWrapperBC reg2;
|
||||
reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg3;
|
||||
reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapperBC reg4;
|
||||
reg4 = CC::template create1<SharedWrapperCC>();
|
||||
SharedWrapperBC reg5;
|
||||
reg5 = CC::template create2<SharedWrapperCC>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool RegRuleTest::onRun() {
|
||||
|
||||
//checkSharedWrapper<SharedWrapper<BaseClass>, SharedWrapper<ChildClass>, BaseClass, ChildClass>();
|
||||
|
||||
{
|
||||
String::SharedWrapper reg1("");
|
||||
String::SharedWrapper reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
String::SharedWrapper reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
String::SharedWrapper reg4 = String::createShared(100);
|
||||
}
|
||||
|
||||
{
|
||||
String::SharedWrapper reg1("");
|
||||
base::SharedWrapper<String> reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
base::SharedWrapper<String> reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
base::SharedWrapper<String> reg4 = String::createShared(100) + "Leonid";
|
||||
}
|
||||
|
||||
{
|
||||
base::SharedWrapper<String> reg1 = String::createShared(100);
|
||||
String::SharedWrapper reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
String::SharedWrapper reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
}
|
||||
|
||||
{
|
||||
String::SharedWrapper reg1(String::createShared(100) + "Leonid");
|
||||
StringSharedWrapper reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
StringSharedWrapper reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
StringSharedWrapper reg4 = String::createShared(100);
|
||||
}
|
||||
|
||||
{
|
||||
StringSharedWrapper reg1 = String::createShared(100);
|
||||
String::SharedWrapper reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
String::SharedWrapper reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
}
|
||||
|
||||
{
|
||||
base::SharedWrapper<String> reg1 = String::createShared(100);
|
||||
StringSharedWrapper reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
StringSharedWrapper reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
}
|
||||
|
||||
{
|
||||
StringSharedWrapper reg1 = String::createShared(100);
|
||||
base::SharedWrapper<String> reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
base::SharedWrapper<String> reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
}
|
||||
|
||||
|
||||
//checkSharedWrapper<PolymorphicSharedWrapper<BaseClass>, PolymorphicSharedWrapper<ChildClass>, BaseClass, ChildClass>();
|
||||
|
||||
/*
|
||||
{
|
||||
SharedWrapper<BaseClass> reg1(new BaseClass);
|
||||
SharedWrapper<BaseClass> reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg3(std::move(reg1));
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg4(BaseClass::create1<SharedWrapper<BaseClass>>());
|
||||
SharedWrapper<BaseClass> reg5(BaseClass::create2<SharedWrapper<BaseClass>>());
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapper<BaseClass> reg1 = new BaseClass;
|
||||
SharedWrapper<BaseClass> reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg4 = BaseClass::create1<SharedWrapper<BaseClass>>();
|
||||
SharedWrapper<BaseClass> reg5 = BaseClass::create2<SharedWrapper<BaseClass>>();
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapper<BaseClass> reg1 = new BaseClass;
|
||||
SharedWrapper<BaseClass> reg2;
|
||||
reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg3;
|
||||
reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg4;
|
||||
reg4 = BaseClass::create1<SharedWrapper<BaseClass>>();
|
||||
SharedWrapper<BaseClass> reg5;
|
||||
reg5 = BaseClass::create2<SharedWrapper<BaseClass>>();
|
||||
}
|
||||
|
||||
//---
|
||||
|
||||
{
|
||||
SharedWrapper<ChildClass> reg1(new ChildClass);
|
||||
SharedWrapper<BaseClass> reg2(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg3(std::move(reg1));
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg4(ChildClass::create1<SharedWrapper<ChildClass>>());
|
||||
SharedWrapper<BaseClass> reg5(ChildClass::create2<SharedWrapper<ChildClass>>());
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapper<ChildClass> reg1 = new ChildClass;
|
||||
SharedWrapper<BaseClass> reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg4 = ChildClass::create1<SharedWrapper<ChildClass>>();
|
||||
SharedWrapper<BaseClass> reg5 = ChildClass::create2<SharedWrapper<ChildClass>>();
|
||||
}
|
||||
|
||||
{
|
||||
SharedWrapper<ChildClass> reg1 = new ChildClass;
|
||||
SharedWrapper<BaseClass> reg2;
|
||||
reg2 = reg1;
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg3;
|
||||
reg3 = std::move(reg1);
|
||||
OATPP_ASSERT(!reg1.isNull());
|
||||
SharedWrapper<BaseClass> reg4;
|
||||
reg4 = ChildClass::create1<SharedWrapper<ChildClass>>();
|
||||
SharedWrapper<BaseClass> reg5;
|
||||
reg5 = ChildClass::create2<SharedWrapper<ChildClass>>();
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
42
core/test/base/RegRuleTest.hpp
Normal file
42
core/test/base/RegRuleTest.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_base_RegRuleTest_hpp
|
||||
#define oatpp_test_base_RegRuleTest_hpp
|
||||
|
||||
#include "../UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace base {
|
||||
|
||||
class RegRuleTest : public UnitTest{
|
||||
public:
|
||||
|
||||
RegRuleTest():UnitTest("TEST[base::RegRuleTest]"){}
|
||||
bool onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_test_base_RegRuleTest_hpp */
|
126
core/test/base/collection/LinkedListTest.cpp
Normal file
126
core/test/base/collection/LinkedListTest.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "LinkedListTest.hpp"
|
||||
|
||||
#include "../../../src/base/String.hpp"
|
||||
#include "../../../src/collection/LinkedList.hpp"
|
||||
#include "../../Checker.hpp"
|
||||
#include <list>
|
||||
|
||||
namespace oatpp { namespace test { namespace collection {
|
||||
|
||||
namespace {
|
||||
|
||||
class TestObject : public oatpp::base::Controllable {
|
||||
public:
|
||||
SHARED_OBJECT_POOL(TestObject_Pool2, TestObject, 32)
|
||||
public:
|
||||
TestObject()
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<TestObject> createShared2(){
|
||||
return std::shared_ptr<TestObject>(new TestObject);
|
||||
}
|
||||
|
||||
static std::shared_ptr<TestObject> createShared(){
|
||||
return TestObject_Pool2::allocateShared();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void testListPerformance(v_int32 iterationsCount){
|
||||
|
||||
auto list = oatpp::collection::LinkedList<std::shared_ptr<TestObject>>::createShared();
|
||||
|
||||
for(v_int32 i = 0; i < iterationsCount; i++){
|
||||
list->pushBack(TestObject::createShared());
|
||||
}
|
||||
|
||||
auto curr = list->getFirstNode();
|
||||
while (curr != nullptr) {
|
||||
auto data = curr->getData();
|
||||
curr = curr->getNext();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testStdListPerformance(v_int32 iterationsCount){
|
||||
|
||||
std::list<std::shared_ptr<TestObject>> list;
|
||||
|
||||
for(v_int32 i = 0; i < iterationsCount; i++){
|
||||
list.push_back(TestObject::createShared());
|
||||
}
|
||||
|
||||
auto it = list.begin();
|
||||
while (it != list.end()) {
|
||||
auto data = *it;
|
||||
it++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool LinkedListTest::onRun() {
|
||||
|
||||
//for(v_int32 i = 0; i < 10000000; i++){
|
||||
//auto ptr = TestObject::createShared2();
|
||||
//}
|
||||
|
||||
// 398689
|
||||
for(v_int32 i = 0; i < 1000000; i++) {
|
||||
auto s = oatpp::base::String::createShared(1024);
|
||||
}
|
||||
|
||||
oatpp::base::String::SharedWrapper s1 = "Leonid";
|
||||
oatpp::base::String::SharedWrapper s2 = "Stryzhevskyi";
|
||||
oatpp::base::String::SharedWrapper s3 = s1 + " " + s2;
|
||||
OATPP_LOGD("Hello!", "s1='%s', s2='%s'", s1->c_str(), s2->c_str());
|
||||
OATPP_LOGD("Hello!", "s3='%s'", s3->c_str());
|
||||
|
||||
/*
|
||||
v_int32 iterationsCount = 100000;
|
||||
|
||||
{
|
||||
PerformanceChecker checker("oatpp::collection::LinkedList pushBack time");
|
||||
for(v_int32 i = 0; i < 10; i ++) {
|
||||
testListPerformance(iterationsCount);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceChecker checker("std::list pushBack time");
|
||||
for(v_int32 i = 0; i < 10; i ++) {
|
||||
testStdListPerformance(iterationsCount);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
42
core/test/base/collection/LinkedListTest.hpp
Normal file
42
core/test/base/collection/LinkedListTest.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_base_collection_LinkedListTest_hpp
|
||||
#define oatpp_test_base_collection_LinkedListTest_hpp
|
||||
|
||||
#include "../../UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace collection {
|
||||
|
||||
class LinkedListTest : public UnitTest{
|
||||
public:
|
||||
|
||||
LinkedListTest():UnitTest("TEST[oatpp::collection::LinkedListTest]"){}
|
||||
bool onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_test_base_collection_LinkedListTest_hpp */
|
197
core/test/base/memory/MemoryPoolTest.cpp
Normal file
197
core/test/base/memory/MemoryPoolTest.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "MemoryPoolTest.hpp"
|
||||
|
||||
#include "../../../src/base/memory/MemoryPool.hpp"
|
||||
#include "../../Checker.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace memory {
|
||||
|
||||
namespace {
|
||||
|
||||
class TestClass{
|
||||
public:
|
||||
|
||||
TestClass(v_int32 p)
|
||||
:a (p)
|
||||
{
|
||||
}
|
||||
|
||||
const v_int32 a;
|
||||
|
||||
};
|
||||
|
||||
void doGarbageAllocsStdNew(v_int32 garbageNumber){
|
||||
|
||||
TestClass** garbage = new TestClass* [garbageNumber];
|
||||
|
||||
for(v_int32 i = 0; i < garbageNumber; i++){
|
||||
garbage[i] = new TestClass(-100);
|
||||
}
|
||||
|
||||
for(v_int32 i = 0; i < garbageNumber; i++){
|
||||
delete garbage[i];
|
||||
}
|
||||
|
||||
delete [] garbage;
|
||||
|
||||
}
|
||||
|
||||
void testStdNew(v_int32 objectsNumber, v_int32 garbageNumber, v_int32 chunkSize){
|
||||
|
||||
TestClass** objects = new TestClass* [objectsNumber];
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
objects[i] = new TestClass(i);
|
||||
}
|
||||
|
||||
doGarbageAllocsStdNew(garbageNumber);
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
OATPP_ASSERT(objects[i]->a == i);
|
||||
}
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
delete objects[i];
|
||||
}
|
||||
|
||||
doGarbageAllocsStdNew(garbageNumber);
|
||||
|
||||
delete [] objects;
|
||||
|
||||
}
|
||||
|
||||
void doGarbageAllocs(base::memory::MemoryPool& pool, v_int32 garbageNumber){
|
||||
|
||||
TestClass** garbage = new TestClass* [garbageNumber];
|
||||
|
||||
for(v_int32 i = 0; i < garbageNumber; i++){
|
||||
garbage[i] = new (pool.obtain()) TestClass(-100);
|
||||
}
|
||||
|
||||
for(v_int32 i = 0; i < garbageNumber; i++){
|
||||
oatpp::base::memory::MemoryPool::free(garbage[i]);
|
||||
}
|
||||
|
||||
delete [] garbage;
|
||||
|
||||
}
|
||||
|
||||
void testPool(v_int32 objectsNumber, v_int32 garbageNumber, v_int32 chunkSize){
|
||||
|
||||
static base::memory::MemoryPool pool("MemoryPoolTest::Pool2", sizeof(TestClass), chunkSize);
|
||||
|
||||
TestClass** objects = new TestClass* [objectsNumber];
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
objects[i] = new (pool.obtain()) TestClass(i);
|
||||
}
|
||||
|
||||
doGarbageAllocs(pool, garbageNumber);
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
OATPP_ASSERT(objects[i]->a == i);
|
||||
}
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
auto obj = objects[i];
|
||||
obj->~TestClass();
|
||||
oatpp::base::memory::MemoryPool::free(obj);
|
||||
}
|
||||
|
||||
doGarbageAllocs(pool, garbageNumber);
|
||||
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
OATPP_ASSERT(objects[i]->a == -100);
|
||||
}
|
||||
|
||||
delete [] objects;
|
||||
|
||||
OATPP_ASSERT(pool.getObjectsCount() == 0);
|
||||
|
||||
}
|
||||
|
||||
void doStdSimpleAlloc(){
|
||||
TestClass* obj = new TestClass(10);
|
||||
delete obj;
|
||||
}
|
||||
|
||||
void doPoolSimpleAlloc(){
|
||||
static base::memory::MemoryPool pool("MemoryPoolTest::Pool3", sizeof(TestClass), 128);
|
||||
TestClass* obj = new (pool.obtain()) TestClass(10);
|
||||
obj->~TestClass();
|
||||
oatpp::base::memory::MemoryPool::free(obj);
|
||||
}
|
||||
|
||||
void doStackAlloc(){
|
||||
TestClass a(10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool MemoryPoolTest::onRun() {
|
||||
|
||||
const v_int32 objectsNumber = 1000000;
|
||||
const v_int32 garbageNumber = 1000000;
|
||||
const v_int32 chunkSize = 128;
|
||||
|
||||
{
|
||||
PerformanceChecker checker("Alloc Time - Pool");
|
||||
testPool(objectsNumber, garbageNumber, chunkSize);
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceChecker checker("Alloc Time - new");
|
||||
testStdNew(objectsNumber, garbageNumber, chunkSize);
|
||||
}
|
||||
|
||||
v_int32 iterationsCount = 10000000;
|
||||
|
||||
{
|
||||
PerformanceChecker checker("doStdSimpleAlloc time:");
|
||||
for(v_int32 i = 0; i < iterationsCount; i++){
|
||||
doStdSimpleAlloc();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceChecker checker("doPoolSimpleAlloc time:");
|
||||
for(v_int32 i = 0; i < iterationsCount; i++){
|
||||
doPoolSimpleAlloc();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceChecker checker("doStackAlloc time:");
|
||||
for(v_int32 i = 0; i < iterationsCount; i++){
|
||||
doStackAlloc();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}}}
|
42
core/test/base/memory/MemoryPoolTest.hpp
Normal file
42
core/test/base/memory/MemoryPoolTest.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 test_memory_MemoryPoolTest_hpp
|
||||
#define test_memory_MemoryPoolTest_hpp
|
||||
|
||||
#include "../../UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace memory {
|
||||
|
||||
class MemoryPoolTest : public UnitTest{
|
||||
public:
|
||||
|
||||
MemoryPoolTest():UnitTest("TEST[base::memory::MemoryPoolTest]"){}
|
||||
bool onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* test_memory_MemoryPoolTest_hpp */
|
129
core/test/base/memory/PerfTest.cpp
Normal file
129
core/test/base/memory/PerfTest.cpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "PerfTest.hpp"
|
||||
|
||||
#include "../../../src/collection/LinkedList.hpp"
|
||||
#include "../../../src/base/String.hpp"
|
||||
#include "../../../src/concurrency/Thread.hpp"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace oatpp { namespace test { namespace memory {
|
||||
|
||||
namespace {
|
||||
|
||||
class TestBase {
|
||||
public:
|
||||
|
||||
static void* operator new(std::size_t sz) {
|
||||
if(sz != sizeof(TestBase)){
|
||||
throw std::runtime_error("wrong object size");
|
||||
}
|
||||
return ::operator new(sz);
|
||||
}
|
||||
|
||||
static void operator delete(void* ptr, std::size_t sz) {
|
||||
if(sz != sizeof(TestBase)){
|
||||
throw std::runtime_error("wrong object size");
|
||||
}
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class TestChild : public oatpp::base::Controllable, public TestBase {
|
||||
public:
|
||||
|
||||
static void* operator new(std::size_t sz) {
|
||||
return ::operator new(sz);
|
||||
}
|
||||
|
||||
static void operator delete(void* ptr, std::size_t sz) {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class Task : public oatpp::concurrency::Runnable, public oatpp::base::Controllable {
|
||||
private:
|
||||
std::shared_ptr<TestBase> m_shared;
|
||||
public:
|
||||
|
||||
Task(const std::shared_ptr<TestBase>& shared)
|
||||
: m_shared(shared)
|
||||
{}
|
||||
|
||||
static std::shared_ptr<Task> createShared(const std::shared_ptr<TestBase>& shared){
|
||||
return std::shared_ptr<Task>(new Task(shared));
|
||||
}
|
||||
|
||||
void run() override {
|
||||
for(v_int32 i = 0; i < 10; i ++) {
|
||||
std::shared_ptr<TestBase> shared(new TestChild());
|
||||
}
|
||||
/*for(v_int32 i = 0; i < 1000000; i ++) {
|
||||
std::shared_ptr<TestClass> shared = m_shared;
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
bool PerfTest::onRun() {
|
||||
|
||||
v_int32 iterations = 1;
|
||||
v_int32 threadCount = 100;
|
||||
|
||||
OATPP_LOGD(TAG, "size=%d", sizeof(TestBase));
|
||||
|
||||
for(int i = 0; i < iterations; i++) {
|
||||
|
||||
auto threads = oatpp::collection::LinkedList<std::shared_ptr<oatpp::concurrency::Thread>>::createShared(); ;
|
||||
|
||||
for(v_int32 n = 0; n < threadCount; n++) {
|
||||
std::shared_ptr<TestBase> shared;
|
||||
std::shared_ptr<Task> task = Task::createShared(shared);
|
||||
auto thread = oatpp::concurrency::Thread::createShared(task);
|
||||
threads->pushBack(thread);
|
||||
}
|
||||
|
||||
threads->forEach([](const std::shared_ptr<oatpp::concurrency::Thread>& thread){
|
||||
thread->join();
|
||||
});
|
||||
|
||||
/*auto it = threads.begin();
|
||||
while (it != threads.end()) {
|
||||
(*it)->join();
|
||||
it++;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
42
core/test/base/memory/PerfTest.hpp
Normal file
42
core/test/base/memory/PerfTest.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 PerfTest_hpp
|
||||
#define PerfTest_hpp
|
||||
|
||||
#include "../../UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace memory {
|
||||
|
||||
class PerfTest : public UnitTest{
|
||||
public:
|
||||
|
||||
PerfTest():UnitTest("TEST[base::memory::PerfTest]"){}
|
||||
bool onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* PerfTest_hpp */
|
140
encoding/src/Hex.cpp
Normal file
140
encoding/src/Hex.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Hex.hpp"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace oatpp { namespace encoding {
|
||||
|
||||
const char* const Hex::ERROR_UNKNOWN_SYMBOL = "UNKNOWN_SYMBOL";
|
||||
|
||||
const v_char8 Hex::A_D[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
/*
|
||||
const v_word16 Hex::A_W16[] = {
|
||||
htons('0' | ('0' << 8)), htons('1' | ('0' << 8)), htons('2' | ('0' << 8)), htons('3' | ('0' << 8)), htons('4' | ('0' << 8)),
|
||||
htons('5' | ('0' << 8)), htons('6' | ('0' << 8)), htons('7' | ('0' << 8)), htons('8' | ('0' << 8)), htons('9' | ('0' << 8)),
|
||||
htons('A' | ('0' << 8)), htons('B' | ('0' << 8)), htons('C' | ('0' << 8)), htons('D' | ('0' << 8)), htons('E' | ('0' << 8)),
|
||||
htons('F' | ('0' << 8)), htons('0' | ('1' << 8)), htons('1' | ('1' << 8)), htons('2' | ('1' << 8)), htons('3' | ('1' << 8)),
|
||||
htons('4' | ('1' << 8)), htons('5' | ('1' << 8)), htons('6' | ('1' << 8)), htons('7' | ('1' << 8)), htons('8' | ('1' << 8)),
|
||||
htons('9' | ('1' << 8)), htons('A' | ('1' << 8)), htons('B' | ('1' << 8)), htons('C' | ('1' << 8)), htons('D' | ('1' << 8)),
|
||||
htons('E' | ('1' << 8)), htons('F' | ('1' << 8)), htons('0' | ('2' << 8)), htons('1' | ('2' << 8)), htons('2' | ('2' << 8)),
|
||||
htons('3' | ('2' << 8)), htons('4' | ('2' << 8)), htons('5' | ('2' << 8)), htons('6' | ('2' << 8)), htons('7' | ('2' << 8)),
|
||||
htons('8' | ('2' << 8)), htons('9' | ('2' << 8)), htons('A' | ('2' << 8)), htons('B' | ('2' << 8)), htons('C' | ('2' << 8)),
|
||||
htons('D' | ('2' << 8)), htons('E' | ('2' << 8)), htons('F' | ('2' << 8)), htons('0' | ('3' << 8)), htons('1' | ('3' << 8)),
|
||||
htons('2' | ('3' << 8)), htons('3' | ('3' << 8)), htons('4' | ('3' << 8)), htons('5' | ('3' << 8)), htons('6' | ('3' << 8)),
|
||||
htons('7' | ('3' << 8)), htons('8' | ('3' << 8)), htons('9' | ('3' << 8)), htons('A' | ('3' << 8)), htons('B' | ('3' << 8)),
|
||||
htons('C' | ('3' << 8)), htons('D' | ('3' << 8)), htons('E' | ('3' << 8)), htons('F' | ('3' << 8)), htons('0' | ('4' << 8)),
|
||||
htons('1' | ('4' << 8)), htons('2' | ('4' << 8)), htons('3' | ('4' << 8)), htons('4' | ('4' << 8)), htons('5' | ('4' << 8)),
|
||||
htons('6' | ('4' << 8)), htons('7' | ('4' << 8)), htons('8' | ('4' << 8)), htons('9' | ('4' << 8)), htons('A' | ('4' << 8)),
|
||||
htons('B' | ('4' << 8)), htons('C' | ('4' << 8)), htons('D' | ('4' << 8)), htons('E' | ('4' << 8)), htons('F' | ('4' << 8)),
|
||||
htons('0' | ('5' << 8)), htons('1' | ('5' << 8)), htons('2' | ('5' << 8)), htons('3' | ('5' << 8)), htons('4' | ('5' << 8)),
|
||||
htons('5' | ('5' << 8)), htons('6' | ('5' << 8)), htons('7' | ('5' << 8)), htons('8' | ('5' << 8)), htons('9' | ('5' << 8)),
|
||||
htons('A' | ('5' << 8)), htons('B' | ('5' << 8)), htons('C' | ('5' << 8)), htons('D' | ('5' << 8)), htons('E' | ('5' << 8)),
|
||||
htons('F' | ('5' << 8)), htons('0' | ('6' << 8)), htons('1' | ('6' << 8)), htons('2' | ('6' << 8)), htons('3' | ('6' << 8)),
|
||||
htons('4' | ('6' << 8)), htons('5' | ('6' << 8)), htons('6' | ('6' << 8)), htons('7' | ('6' << 8)), htons('8' | ('6' << 8)),
|
||||
htons('9' | ('6' << 8)), htons('A' | ('6' << 8)), htons('B' | ('6' << 8)), htons('C' | ('6' << 8)), htons('D' | ('6' << 8)),
|
||||
htons('E' | ('6' << 8)), htons('F' | ('6' << 8)), htons('0' | ('7' << 8)), htons('1' | ('7' << 8)), htons('2' | ('7' << 8)),
|
||||
htons('3' | ('7' << 8)), htons('4' | ('7' << 8)), htons('5' | ('7' << 8)), htons('6' | ('7' << 8)), htons('7' | ('7' << 8)),
|
||||
htons('8' | ('7' << 8)), htons('9' | ('7' << 8)), htons('A' | ('7' << 8)), htons('B' | ('7' << 8)), htons('C' | ('7' << 8)),
|
||||
htons('D' | ('7' << 8)), htons('E' | ('7' << 8)), htons('F' | ('7' << 8)), htons('0' | ('8' << 8)), htons('1' | ('8' << 8)),
|
||||
htons('2' | ('8' << 8)), htons('3' | ('8' << 8)), htons('4' | ('8' << 8)), htons('5' | ('8' << 8)), htons('6' | ('8' << 8)),
|
||||
htons('7' | ('8' << 8)), htons('8' | ('8' << 8)), htons('9' | ('8' << 8)), htons('A' | ('8' << 8)), htons('B' | ('8' << 8)),
|
||||
htons('C' | ('8' << 8)), htons('D' | ('8' << 8)), htons('E' | ('8' << 8)), htons('F' | ('8' << 8)), htons('0' | ('9' << 8)),
|
||||
htons('1' | ('9' << 8)), htons('2' | ('9' << 8)), htons('3' | ('9' << 8)), htons('4' | ('9' << 8)), htons('5' | ('9' << 8)),
|
||||
htons('6' | ('9' << 8)), htons('7' | ('9' << 8)), htons('8' | ('9' << 8)), htons('9' | ('9' << 8)), htons('A' | ('9' << 8)),
|
||||
htons('B' | ('9' << 8)), htons('C' | ('9' << 8)), htons('D' | ('9' << 8)), htons('E' | ('9' << 8)), htons('F' | ('9' << 8)),
|
||||
htons('0' | ('A' << 8)), htons('1' | ('A' << 8)), htons('2' | ('A' << 8)), htons('3' | ('A' << 8)), htons('4' | ('A' << 8)),
|
||||
htons('5' | ('A' << 8)), htons('6' | ('A' << 8)), htons('7' | ('A' << 8)), htons('8' | ('A' << 8)), htons('9' | ('A' << 8)),
|
||||
htons('A' | ('A' << 8)), htons('B' | ('A' << 8)), htons('C' | ('A' << 8)), htons('D' | ('A' << 8)), htons('E' | ('A' << 8)),
|
||||
htons('F' | ('A' << 8)), htons('0' | ('B' << 8)), htons('1' | ('B' << 8)), htons('2' | ('B' << 8)), htons('3' | ('B' << 8)),
|
||||
htons('4' | ('B' << 8)), htons('5' | ('B' << 8)), htons('6' | ('B' << 8)), htons('7' | ('B' << 8)), htons('8' | ('B' << 8)),
|
||||
htons('9' | ('B' << 8)), htons('A' | ('B' << 8)), htons('B' | ('B' << 8)), htons('C' | ('B' << 8)), htons('D' | ('B' << 8)),
|
||||
htons('E' | ('B' << 8)), htons('F' | ('B' << 8)), htons('0' | ('C' << 8)), htons('1' | ('C' << 8)), htons('2' | ('C' << 8)),
|
||||
htons('3' | ('C' << 8)), htons('4' | ('C' << 8)), htons('5' | ('C' << 8)), htons('6' | ('C' << 8)), htons('7' | ('C' << 8)),
|
||||
htons('8' | ('C' << 8)), htons('9' | ('C' << 8)), htons('A' | ('C' << 8)), htons('B' | ('C' << 8)), htons('C' | ('C' << 8)),
|
||||
htons('D' | ('C' << 8)), htons('E' | ('C' << 8)), htons('F' | ('C' << 8)), htons('0' | ('D' << 8)), htons('1' | ('D' << 8)),
|
||||
htons('2' | ('D' << 8)), htons('3' | ('D' << 8)), htons('4' | ('D' << 8)), htons('5' | ('D' << 8)), htons('6' | ('D' << 8)),
|
||||
htons('7' | ('D' << 8)), htons('8' | ('D' << 8)), htons('9' | ('D' << 8)), htons('A' | ('D' << 8)), htons('B' | ('D' << 8)),
|
||||
htons('C' | ('D' << 8)), htons('D' | ('D' << 8)), htons('E' | ('D' << 8)), htons('F' | ('D' << 8)), htons('0' | ('E' << 8)),
|
||||
htons('1' | ('E' << 8)), htons('2' | ('E' << 8)), htons('3' | ('E' << 8)), htons('4' | ('E' << 8)), htons('5' | ('E' << 8)),
|
||||
htons('6' | ('E' << 8)), htons('7' | ('E' << 8)), htons('8' | ('E' << 8)), htons('9' | ('E' << 8)), htons('A' | ('E' << 8)),
|
||||
htons('B' | ('E' << 8)), htons('C' | ('E' << 8)), htons('D' | ('E' << 8)), htons('E' | ('E' << 8)), htons('F' | ('E' << 8)),
|
||||
htons('0' | ('F' << 8)), htons('1' | ('F' << 8)), htons('2' | ('F' << 8)), htons('3' | ('F' << 8)), htons('4' | ('F' << 8)),
|
||||
htons('5' | ('F' << 8)), htons('6' | ('F' << 8)), htons('7' | ('F' << 8)), htons('8' | ('F' << 8)), htons('9' | ('F' << 8)),
|
||||
htons('A' | ('F' << 8)), htons('B' | ('F' << 8)), htons('C' | ('F' << 8)), htons('D' | ('F' << 8)), htons('E' | ('F' << 8)),
|
||||
htons('F' | ('F' << 8))
|
||||
};
|
||||
*/
|
||||
|
||||
void Hex::writeWord16(v_word16 value, p_char8 buffer){
|
||||
*((p_word32) buffer) = htonl((A_D[ value & 0x000F ] ) |
|
||||
(A_D[(value & 0x00F0) >> 4] << 8) |
|
||||
(A_D[(value & 0x0F00) >> 8] << 16) |
|
||||
(A_D[(value & 0xF000) >> 12] << 24));
|
||||
|
||||
//*((p_int16) buffer) = A_W16[(value >> 8) & 0xFF];
|
||||
//*((p_int16) (buffer + 2)) = A_W16[value & 0xFF];
|
||||
|
||||
}
|
||||
|
||||
void Hex::writeWord32(v_word32 value, p_char8 buffer){
|
||||
writeWord16(value >> 16, buffer);
|
||||
writeWord16(value, buffer + 4);
|
||||
}
|
||||
|
||||
const char* Hex::readWord16(p_char8 buffer, v_word16& value) {
|
||||
value = 0;
|
||||
for(v_int32 i = 0; i < 4; i++){
|
||||
v_char8 a = buffer[i];
|
||||
if(a >= '0' && a <= '9') {
|
||||
value |= (a - '0') << ((3 - i) << 2);
|
||||
} else if (a >= 'A' && a <= 'F') {
|
||||
value |= (a - 'A' + 10) << ((3 - i) << 2);
|
||||
} else if (a >= 'a' && a <= 'f') {
|
||||
value |= (a - 'a' + 10) << ((3 - i) << 2);
|
||||
} else {
|
||||
return ERROR_UNKNOWN_SYMBOL;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* Hex::readWord32(p_char8 buffer, v_word32& value) {
|
||||
value = 0;
|
||||
for(v_int32 i = 0; i < 8; i++){
|
||||
v_char8 a = buffer[i];
|
||||
if(a >= '0' && a <= '9') {
|
||||
value |= (a - '0') << ((7 - i) << 2);
|
||||
} else if (a >= 'A' && a <= 'F') {
|
||||
value |= (a - 'A' + 10) << ((7 - i) << 2);
|
||||
} else if (a >= 'a' && a <= 'f') {
|
||||
value |= (a - 'a' + 10) << ((7 - i) << 2);
|
||||
} else {
|
||||
return ERROR_UNKNOWN_SYMBOL;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}}
|
53
encoding/src/Hex.hpp
Normal file
53
encoding/src/Hex.hpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_encoding_Hex_hpp
|
||||
#define oatpp_encoding_Hex_hpp
|
||||
|
||||
#include "../../../oatpp-lib/core/src/data/stream/Stream.hpp"
|
||||
|
||||
#include "../../../oatpp-lib/core/src/base/SharedWrapper.hpp"
|
||||
#include "../../../oatpp-lib/core/src/base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace encoding {
|
||||
|
||||
class Hex {
|
||||
public:
|
||||
static const v_char8 A_D[];
|
||||
static const v_word16 A_W16[];
|
||||
public:
|
||||
static const char* const ERROR_UNKNOWN_SYMBOL;
|
||||
public:
|
||||
|
||||
static void writeWord16(v_word16 value, p_char8 buffer);
|
||||
static void writeWord32(v_word32 value, p_char8 buffer);
|
||||
|
||||
static const char* readWord16(p_char8 buffer, v_word16& value);
|
||||
static const char* readWord32(p_char8 buffer, v_word32& value);
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_encoding_Hex_hpp */
|
161
encoding/src/Unicode.cpp
Normal file
161
encoding/src/Unicode.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Unicode.hpp"
|
||||
|
||||
#include "./Hex.hpp"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace oatpp { namespace encoding {
|
||||
|
||||
v_int32 Unicode::getUtf8CharSequenceLength(v_char8 firstByte) {
|
||||
|
||||
if(firstByte < 128){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if((firstByte | 192) != firstByte){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((firstByte | 32) != firstByte){
|
||||
return 2;
|
||||
} else if((firstByte | 16) != firstByte){
|
||||
return 3;
|
||||
} else if((firstByte | 8) != firstByte){
|
||||
return 4;
|
||||
} else if((firstByte | 4) != firstByte){
|
||||
return 5;
|
||||
} else if((firstByte | 2) != firstByte){
|
||||
return 6;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
v_int32 Unicode::getUtf8CharSequenceLengthForCode(v_word32 code){
|
||||
if(code < 128) {
|
||||
return 1;
|
||||
} else if(code < 0x00000800){
|
||||
return 2;
|
||||
} else if(code < 0x00010000){
|
||||
return 3;
|
||||
} else if(code < 0x00200000){
|
||||
return 4;
|
||||
} else if(code < 0x04000000){
|
||||
return 5;
|
||||
} else {
|
||||
return 6;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
v_int32 Unicode::encodeUtf8Char(p_char8 sequence, v_int32& length){
|
||||
v_char8 byte = sequence[0];
|
||||
if(byte > 127){
|
||||
v_int32 code;
|
||||
if((byte | 32) != byte){
|
||||
length = 2;
|
||||
code = ((31 & byte) << 6) | (sequence[1] & 63);
|
||||
return code;
|
||||
} else if((byte | 16) != byte){
|
||||
code = (15 & byte) << 12;
|
||||
length = 3;
|
||||
} else if((byte | 8) != byte){
|
||||
length = 4;
|
||||
v_int32 value = *((p_int32)sequence);
|
||||
code = ((7 & byte) << 18) |
|
||||
(((value >> 24) & 0xFF) & 63) |
|
||||
(((value >> 16) & 0xFF) & 63) << 6 |
|
||||
(((value >> 8) & 0xFF) & 63) << 12;
|
||||
return code;
|
||||
} else if((byte | 4) != byte){
|
||||
code = (3 & byte) << 24;
|
||||
length = 5;
|
||||
} else if((byte | 2) != byte){
|
||||
code = (1 & byte) << 30;
|
||||
length = 6;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
v_char8 bitIndex = 0;
|
||||
for(v_int32 i = length; i > 1; i--){
|
||||
code |= (sequence[i - 1] & 63) << bitIndex;
|
||||
bitIndex += 6;
|
||||
}
|
||||
return code;
|
||||
} else {
|
||||
length = 1;
|
||||
return byte;
|
||||
}
|
||||
}
|
||||
|
||||
v_int32 Unicode::decodeUtf8Char(v_int32 code, p_char8 buffer) {
|
||||
if(code >= 0x00000080 && code < 0x00000800){
|
||||
*((p_int16) buffer) = htons(((((code >> 6) & 31) | 192) << 8) | ((code & 63) | 128));
|
||||
return 2;
|
||||
} else if(code >= 0x00000800 && code < 0x00010000){
|
||||
*((p_int16) buffer) = htons((((( code >> 12 ) & 15) | 224) << 8) |
|
||||
(((code >> 6 ) & 63) | 128));
|
||||
buffer[2] = (code & 63) | 128;
|
||||
return 3;
|
||||
} else if(code >= 0x00010000 && code < 0x00200000){
|
||||
*((p_int32) buffer) = htonl(((((code >> 18 ) & 7) | 240) << 24) |
|
||||
((((code >> 12 ) & 63) | 128) << 16) |
|
||||
((((code >> 6 ) & 63) | 128) << 8) |
|
||||
(( code & 63) | 128) );
|
||||
return 4;
|
||||
} else if(code >= 0x00200000 && code < 0x04000000){
|
||||
*((p_int32) buffer) = htonl(((((code >> 24 ) & 3) | 248) << 24) |
|
||||
((((code >> 18 ) & 63) | 128) << 16) |
|
||||
((((code >> 12 ) & 63) | 128) << 8) |
|
||||
(((code >> 6 ) & 63) | 128));
|
||||
buffer[4] = (code & 63) | 128;
|
||||
return 5;
|
||||
} else if(code >= 0x04000000){
|
||||
*((p_int32) buffer) = htonl(((((code >> 30 ) & 1) | 252) << 24) |
|
||||
((((code >> 24 ) & 63) | 128) << 16) |
|
||||
((((code >> 18 ) & 63) | 128) << 8) |
|
||||
(((code >> 12 ) & 63) | 128));
|
||||
*((p_int16) &buffer[4]) = htons(((((code >> 6 ) & 63) | 128) << 8) | (code & 63));
|
||||
return 6;
|
||||
}
|
||||
buffer[0] = code;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Unicode::codeToUtf16SurrogatePair(v_int32 code, v_int16& high, v_int16& low){
|
||||
code -= 0x010000;
|
||||
high = 0xD800 + ((code >> 10) & 1023);
|
||||
low = 0xDC00 + (code & 1023);
|
||||
}
|
||||
|
||||
v_int32 Unicode::utf16SurrogatePairToCode(v_int16 high, v_int16 low){
|
||||
return (((low - 0xDC00) & 1023) | (((high - 0xD800) & 1023) << 10)) + 0x010000;
|
||||
}
|
||||
|
||||
}}
|
44
encoding/src/Unicode.hpp
Normal file
44
encoding/src/Unicode.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_encoding_Unicode_hpp
|
||||
#define oatpp_encoding_Unicode_hpp
|
||||
|
||||
#include "../../../oatpp-lib/core/src/base/Environment.hpp"
|
||||
|
||||
namespace oatpp { namespace encoding {
|
||||
|
||||
class Unicode {
|
||||
public:
|
||||
static v_int32 getUtf8CharSequenceLength(v_char8 firstByte);
|
||||
static v_int32 getUtf8CharSequenceLengthForCode(v_word32 code);
|
||||
static v_int32 encodeUtf8Char(p_char8 sequence, v_int32& length); // returns code
|
||||
static v_int32 decodeUtf8Char(v_int32 code, p_char8 buffer); // returns length
|
||||
static void codeToUtf16SurrogatePair(v_int32 code, v_int16& high, v_int16& low);
|
||||
static v_int32 utf16SurrogatePairToCode(v_int16 high, v_int16 low);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_encoding_Unicode_hpp */
|
137
encoding/test/UnicodeTest.cpp
Normal file
137
encoding/test/UnicodeTest.cpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "UnicodeTest.hpp"
|
||||
|
||||
#include "../src/Hex.hpp"
|
||||
#include "../src/Unicode.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace encoding {
|
||||
|
||||
namespace {
|
||||
|
||||
void writeBinaryInt(v_int32 value){
|
||||
|
||||
v_char8 buff [37];
|
||||
buff[36] = '\0';
|
||||
v_int32 index = 0;
|
||||
for(v_int32 i = 0; i < 36; i++){
|
||||
if((i + 1) % 9 == 0){
|
||||
buff[i] = ',';
|
||||
} else {
|
||||
v_int32 unit = 1 << index;
|
||||
if((unit & value) == 0){
|
||||
buff[i] = '0';
|
||||
} else {
|
||||
buff[i] = '1';
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
OATPP_LOGD("bin", "value='%s'", (const char*) &buff);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 38327
|
||||
|
||||
bool UnicodeTest::onRun(){
|
||||
|
||||
v_char8 buff[128];
|
||||
v_int32 cnt;
|
||||
|
||||
// 2 byte test
|
||||
|
||||
for(v_int32 c = 128; c < 2048; c ++){
|
||||
v_int32 size = oatpp::encoding::Unicode::decodeUtf8Char(c, buff);
|
||||
OATPP_ASSERT(size == 2);
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(buff, cnt);
|
||||
OATPP_ASSERT(cnt == 2);
|
||||
OATPP_ASSERT(code == c);
|
||||
}
|
||||
|
||||
// 3 byte test
|
||||
|
||||
for(v_int32 c = 2048; c < 65536; c ++){
|
||||
v_int32 size = oatpp::encoding::Unicode::decodeUtf8Char(c, buff);
|
||||
OATPP_ASSERT(size == 3);
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(buff, cnt);
|
||||
OATPP_ASSERT(cnt == 3);
|
||||
OATPP_ASSERT(code == c);
|
||||
}
|
||||
|
||||
// 4 byte test
|
||||
|
||||
for(v_int32 c = 65536; c < 2097152; c ++){
|
||||
v_int32 size = oatpp::encoding::Unicode::decodeUtf8Char(c, buff);
|
||||
OATPP_ASSERT(size == 4);
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(buff, cnt);
|
||||
OATPP_ASSERT(cnt == 4);
|
||||
OATPP_ASSERT(code == c);
|
||||
}
|
||||
|
||||
// 5 byte test
|
||||
|
||||
for(v_int32 c = 2097152; c < 67108864; c ++){
|
||||
v_int32 size = oatpp::encoding::Unicode::decodeUtf8Char(c, buff);
|
||||
OATPP_ASSERT(size == 5);
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(buff, cnt);
|
||||
OATPP_ASSERT(cnt == 5);
|
||||
OATPP_ASSERT(code == c);
|
||||
}
|
||||
|
||||
// 6 byte test
|
||||
|
||||
for(v_int32 c = 67108864; c < 2147483647; c ++){
|
||||
v_int32 size = oatpp::encoding::Unicode::decodeUtf8Char(c, buff);
|
||||
OATPP_ASSERT(size == 6);
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(buff, cnt);
|
||||
OATPP_ASSERT(cnt == 6);
|
||||
OATPP_ASSERT(code == c);
|
||||
}
|
||||
// */
|
||||
|
||||
p_char8 sequence = (p_char8)"𐐷";
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(sequence, cnt);
|
||||
|
||||
v_int16 high;
|
||||
v_int16 low;
|
||||
oatpp::encoding::Unicode::codeToUtf16SurrogatePair(code, high, low);
|
||||
v_int32 check = oatpp::encoding::Unicode::utf16SurrogatePairToCode(high, low);
|
||||
writeBinaryInt(code);
|
||||
writeBinaryInt(check);
|
||||
OATPP_ASSERT(code == check);
|
||||
|
||||
for(v_int32 c = 0x010000; c <= 0x10FFFF; c++) {
|
||||
oatpp::encoding::Unicode::codeToUtf16SurrogatePair(code, high, low);
|
||||
check = oatpp::encoding::Unicode::utf16SurrogatePairToCode(high, low);
|
||||
OATPP_ASSERT(code == check);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}
|
41
encoding/test/UnicodeTest.hpp
Normal file
41
encoding/test/UnicodeTest.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_encoding_UnicodeTest_hpp
|
||||
#define oatpp_test_encoding_UnicodeTest_hpp
|
||||
|
||||
#include "../../../oatpp-lib/core/test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace encoding {
|
||||
|
||||
class UnicodeTest : public UnitTest{
|
||||
public:
|
||||
UnicodeTest():UnitTest("TEST[encoding::UnicodeTest]"){}
|
||||
bool onRun() override;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
#endif /* oatpp_test_encoding_UnicodeTest_hpp */
|
84
network/src/Connection.cpp
Normal file
84
network/src/Connection.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Connection.hpp"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
namespace oatpp { namespace network {
|
||||
|
||||
Connection::Connection(Library::v_handle handle)
|
||||
: m_handle(handle)
|
||||
{
|
||||
}
|
||||
|
||||
Connection::~Connection(){
|
||||
close();
|
||||
}
|
||||
|
||||
Connection::Library::v_size Connection::write(const void *buff, Library::v_size count){
|
||||
return Library::handle_write(m_handle, buff, count);
|
||||
}
|
||||
|
||||
Connection::Library::v_size Connection::read(void *buff, Library::v_size count){
|
||||
return Library::handle_read(m_handle, buff, count);
|
||||
}
|
||||
|
||||
v_int32 Connection::shutdown(){
|
||||
return ::shutdown(m_handle, SHUT_RDWR);
|
||||
}
|
||||
|
||||
v_int32 Connection::shutdownRead(){
|
||||
return ::shutdown(m_handle, SHUT_RD);
|
||||
}
|
||||
|
||||
v_int32 Connection::shutdownWrite(){
|
||||
return ::shutdown(m_handle, SHUT_WR);
|
||||
}
|
||||
|
||||
void Connection::prepareGracefulDisconnect(){
|
||||
|
||||
if(::shutdown(m_handle, SHUT_WR) == 0){
|
||||
|
||||
v_int32 times = 0;
|
||||
while(::shutdown(m_handle, SHUT_WR) == 0){
|
||||
times++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
if(times > 0){
|
||||
OATPP_LOGD("Server", "Connection tries to shutdown = %d", times);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::close(){
|
||||
//prepareGracefulDisconnect(); // TODO remove this
|
||||
Library::handle_close(m_handle);
|
||||
}
|
||||
|
||||
|
||||
}}
|
77
network/src/Connection.hpp
Normal file
77
network/src/Connection.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_network_Connection_hpp
|
||||
#define oatpp_network_Connection_hpp
|
||||
|
||||
#include "../../../oatpp-lib/core/src/base/memory/ObjectPool.hpp"
|
||||
|
||||
#include "../../../oatpp-lib/core/src/data/stream/Stream.hpp"
|
||||
|
||||
#include "../../../oatpp-lib/core/src/base/Controllable.hpp"
|
||||
#include "../../../oatpp-lib/core/src/base/SharedWrapper.hpp"
|
||||
#include "../../../oatpp-lib/core/src/base/Environment.hpp"
|
||||
|
||||
#include "../../../oatpp-lib/core/src/os/io/Library.hpp"
|
||||
|
||||
namespace oatpp { namespace network {
|
||||
|
||||
class Connection : public oatpp::base::Controllable, public oatpp::data::stream::IOStream {
|
||||
public:
|
||||
typedef oatpp::os::io::Library Library;
|
||||
public:
|
||||
OBJECT_POOL(Connection_Pool, Connection, 32);
|
||||
SHARED_OBJECT_POOL(Shared_Connection_Pool, Connection, 32);
|
||||
private:
|
||||
Library::v_handle m_handle;
|
||||
void prepareGracefulDisconnect();
|
||||
public:
|
||||
Connection(Library::v_handle handle);
|
||||
public:
|
||||
|
||||
static std::shared_ptr<Connection> createShared(Library::v_handle handle){
|
||||
return Shared_Connection_Pool::allocateShared(handle);
|
||||
}
|
||||
|
||||
~Connection();
|
||||
|
||||
Library::v_size write(const void *buff, Library::v_size count) override;
|
||||
Library::v_size read(void *buff, Library::v_size count) override;
|
||||
|
||||
v_int32 shutdown();
|
||||
v_int32 shutdownRead();
|
||||
v_int32 shutdownWrite();
|
||||
|
||||
void close();
|
||||
|
||||
Library::v_handle getHandle(){
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_network_Connection_hpp */
|
29
network/src/ConnectionProvider.cpp
Normal file
29
network/src/ConnectionProvider.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./ConnectionProvider.hpp"
|
||||
|
||||
namespace oatpp { namespace network {
|
||||
|
||||
}}
|
78
network/src/ConnectionProvider.hpp
Normal file
78
network/src/ConnectionProvider.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_netword_ConnectionsProvider_hpp
|
||||
#define oatpp_netword_ConnectionsProvider_hpp
|
||||
|
||||
#include "../../../oatpp-lib/core/src/data/stream/Stream.hpp"
|
||||
|
||||
namespace oatpp { namespace network {
|
||||
|
||||
class ServerConnectionProvider {
|
||||
public:
|
||||
typedef oatpp::data::stream::IOStream IOStream;
|
||||
protected:
|
||||
v_word16 m_port;
|
||||
public:
|
||||
|
||||
ServerConnectionProvider(v_word16 port)
|
||||
: m_port(port)
|
||||
{}
|
||||
|
||||
virtual std::shared_ptr<IOStream> getConnection() = 0;
|
||||
|
||||
v_word16 getPort(){
|
||||
return m_port;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ClientConnectionProvider {
|
||||
public:
|
||||
typedef oatpp::data::stream::IOStream IOStream;
|
||||
protected:
|
||||
oatpp::base::String::SharedWrapper m_host;
|
||||
v_word16 m_port;
|
||||
public:
|
||||
|
||||
ClientConnectionProvider(const oatpp::base::String::SharedWrapper& host, v_word16 port)
|
||||
: m_host(host)
|
||||
, m_port(port)
|
||||
{}
|
||||
|
||||
virtual std::shared_ptr<IOStream> getConnection() = 0;
|
||||
|
||||
oatpp::base::String::SharedWrapper getHost() {
|
||||
return m_host;
|
||||
}
|
||||
|
||||
v_word16 getPort(){
|
||||
return m_port;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif /* oatpp_netword_ConnectionsProvider_hpp */
|
71
network/src/client/SimpleTCPConnectionProvider.cpp
Normal file
71
network/src/client/SimpleTCPConnectionProvider.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./SimpleTCPConnectionProvider.hpp"
|
||||
|
||||
#include "../Connection.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/data/stream/ChunkedBuffer.hpp"
|
||||
#include "../../../../oatpp-lib/core/test/Checker.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
namespace oatpp { namespace network { namespace client {
|
||||
|
||||
std::shared_ptr<oatpp::data::stream::IOStream> SimpleTCPConnectionProvider::getConnection(){
|
||||
|
||||
struct hostent* host = gethostbyname((const char*) m_host->getData());
|
||||
struct sockaddr_in client;
|
||||
|
||||
if ((host == NULL) || (host->h_addr == NULL)) {
|
||||
OATPP_LOGD("SimpleTCPConnectionProvider", "Error retrieving DNS information.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bzero(&client, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(m_port);
|
||||
memcpy(&client.sin_addr, host->h_addr, host->h_length);
|
||||
|
||||
oatpp::os::io::Library::v_handle clientHandle = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (clientHandle < 0) {
|
||||
OATPP_LOGD("SimpleTCPConnectionProvider", "Error creating socket.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (connect(clientHandle, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
|
||||
oatpp::os::io::Library::handle_close(clientHandle);
|
||||
OATPP_LOGD("SimpleTCPConnectionProvider", "Could not connect");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return oatpp::network::Connection::createShared(clientHandle);
|
||||
|
||||
}
|
||||
|
||||
}}}
|
53
network/src/client/SimpleTCPConnectionProvider.hpp
Normal file
53
network/src/client/SimpleTCPConnectionProvider.hpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_netword_client_SimpleTCPConnectionProvider_hpp
|
||||
#define oatpp_netword_client_SimpleTCPConnectionProvider_hpp
|
||||
|
||||
#include "../ConnectionProvider.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/data/stream/Stream.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/base/String.hpp"
|
||||
|
||||
namespace oatpp { namespace network { namespace client {
|
||||
|
||||
class SimpleTCPConnectionProvider : public base::Controllable, public ClientConnectionProvider {
|
||||
public:
|
||||
SimpleTCPConnectionProvider(const oatpp::base::String::SharedWrapper& host, v_int32 port)
|
||||
: ClientConnectionProvider(host, port)
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<SimpleTCPConnectionProvider>
|
||||
createShared(const oatpp::base::String::SharedWrapper& host, v_int32 port){
|
||||
return std::shared_ptr<SimpleTCPConnectionProvider>(new SimpleTCPConnectionProvider(host, port));
|
||||
}
|
||||
|
||||
std::shared_ptr<IOStream> getConnection() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_netword_client_SimpleTCPConnectionProvider_hpp */
|
25
network/src/server/ConnectionHandler.cpp
Normal file
25
network/src/server/ConnectionHandler.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./ConnectionHandler.hpp"
|
40
network/src/server/ConnectionHandler.hpp
Normal file
40
network/src/server/ConnectionHandler.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef network_server_ConnectionHandler_hpp
|
||||
#define network_server_ConnectionHandler_hpp
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/data/stream/Stream.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/base/SharedWrapper.hpp"
|
||||
|
||||
namespace oatpp { namespace network { namespace server {
|
||||
|
||||
class ConnectionHandler {
|
||||
public:
|
||||
virtual void handleConnection(const std::shared_ptr<oatpp::data::stream::IOStream>& connection) = 0;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* network_server_ConnectionHandler_hpp */
|
83
network/src/server/Server.cpp
Normal file
83
network/src/server/Server.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Server.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/test/Checker.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
namespace oatpp { namespace network { namespace server {
|
||||
|
||||
const v_int32 Server::STATUS_CREATED = 0;
|
||||
const v_int32 Server::STATUS_RUNNING = 1;
|
||||
const v_int32 Server::STATUS_STOPPING = 2;
|
||||
const v_int32 Server::STATUS_DONE = 3;
|
||||
|
||||
void Server::mainLoop(){
|
||||
|
||||
setStatus(STATUS_CREATED, STATUS_RUNNING);
|
||||
|
||||
while(getStatus() == STATUS_RUNNING) {
|
||||
|
||||
auto connection = m_connectionProvider->getConnection();
|
||||
|
||||
if (connection) {
|
||||
if(getStatus() == STATUS_RUNNING){
|
||||
m_connectionHandler->handleConnection(connection);
|
||||
} else {
|
||||
OATPP_LOGD("Server", "Already stopped. Closing connection...");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setStatus(STATUS_DONE);
|
||||
|
||||
}
|
||||
|
||||
void Server::run(){
|
||||
mainLoop();
|
||||
}
|
||||
|
||||
void Server::stop(){
|
||||
setStatus(STATUS_STOPPING);
|
||||
}
|
||||
|
||||
bool Server::setStatus(v_int32 expectedStatus, v_int32 newStatus){
|
||||
v_int32 expected = expectedStatus;
|
||||
return m_status.compare_exchange_weak(expected, newStatus);
|
||||
}
|
||||
|
||||
void Server::setStatus(v_int32 status){
|
||||
m_status.store(status);
|
||||
}
|
||||
|
||||
v_int32 Server::getStatus(){
|
||||
return m_status.load();
|
||||
}
|
||||
|
||||
|
||||
}}}
|
99
network/src/server/Server.hpp
Normal file
99
network/src/server/Server.hpp
Normal file
@ -0,0 +1,99 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 network_server_Server_hpp
|
||||
#define network_server_Server_hpp
|
||||
|
||||
#include "../ConnectionProvider.hpp"
|
||||
|
||||
#include "./ConnectionHandler.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/concurrency/Runnable.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/base/String.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/os/io/Library.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/base/SharedWrapper.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/base/Controllable.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/base/Environment.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace oatpp { namespace network { namespace server {
|
||||
|
||||
class Server : public base::Controllable, public concurrency::Runnable{
|
||||
public:
|
||||
typedef oatpp::os::io::Library Library;
|
||||
private:
|
||||
|
||||
void mainLoop();
|
||||
|
||||
bool setStatus(v_int32 expectedStatus, v_int32 newStatus);
|
||||
void setStatus(v_int32 status);
|
||||
|
||||
private:
|
||||
|
||||
std::atomic<v_int32> m_status;
|
||||
|
||||
std::shared_ptr<base::String> m_port;
|
||||
|
||||
std::shared_ptr<ServerConnectionProvider> m_connectionProvider;
|
||||
std::shared_ptr<ConnectionHandler> m_connectionHandler;
|
||||
|
||||
public:
|
||||
|
||||
Server(
|
||||
const std::shared_ptr<ServerConnectionProvider>& connectionProvider,
|
||||
const std::shared_ptr<ConnectionHandler>& connectionHandler
|
||||
)
|
||||
: m_status(STATUS_CREATED)
|
||||
, m_connectionProvider(connectionProvider)
|
||||
, m_connectionHandler(connectionHandler)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
static const v_int32 STATUS_CREATED;
|
||||
static const v_int32 STATUS_RUNNING;
|
||||
static const v_int32 STATUS_STOPPING;
|
||||
static const v_int32 STATUS_DONE;
|
||||
|
||||
static std::shared_ptr<Server> createShared(const std::shared_ptr<ServerConnectionProvider>& connectionProvider,
|
||||
const std::shared_ptr<ConnectionHandler>& connectionHandler){
|
||||
return std::shared_ptr<Server>(new Server(connectionProvider, connectionHandler));
|
||||
}
|
||||
|
||||
void run() override;
|
||||
|
||||
void stop();
|
||||
|
||||
v_int32 getStatus();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* network_server_Server_hpp */
|
106
network/src/server/SimpleTCPConnectionProvider.cpp
Normal file
106
network/src/server/SimpleTCPConnectionProvider.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./SimpleTCPConnectionProvider.hpp"
|
||||
|
||||
#include "../Connection.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/utils/ConversionUtils.hpp"
|
||||
#include "../../../../oatpp-lib/core/test/Checker.hpp"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
|
||||
namespace oatpp { namespace network { namespace server {
|
||||
|
||||
oatpp::os::io::Library::v_handle SimpleTCPConnectionProvider::instantiateServer(){
|
||||
|
||||
oatpp::os::io::Library::v_handle serverHandle;
|
||||
v_int32 ret;
|
||||
int yes = 1;
|
||||
|
||||
struct sockaddr_in6 addr;
|
||||
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = htons(m_port);
|
||||
addr.sin6_addr = in6addr_any;
|
||||
|
||||
serverHandle = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
|
||||
if(serverHandle < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = setsockopt(serverHandle, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
|
||||
if(ret < 0) {
|
||||
oatpp::os::io::Library::handle_close(serverHandle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = bind(serverHandle, (struct sockaddr *)&addr, sizeof(addr));
|
||||
|
||||
if(ret != 0) {
|
||||
oatpp::os::io::Library::handle_close(serverHandle);
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
ret = listen(serverHandle, 128);
|
||||
if(ret < 0) {
|
||||
oatpp::os::io::Library::handle_close(serverHandle);
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
fcntl(serverHandle, F_SETFL, 0);//O_NONBLOCK);
|
||||
|
||||
return serverHandle;
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::data::stream::IOStream> SimpleTCPConnectionProvider::getConnection(){
|
||||
|
||||
//oatpp::test::PerformanceChecker checker("Accept Checker");
|
||||
|
||||
oatpp::os::io::Library::v_handle handle = accept(m_serverHandle, nullptr, nullptr);
|
||||
|
||||
if (handle < 0) {
|
||||
v_int32 error = errno;
|
||||
if(error == EAGAIN || error == EWOULDBLOCK){
|
||||
return nullptr;
|
||||
} else {
|
||||
OATPP_LOGD("Server", "Error: %d", error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
fcntl(handle, F_SETFL, 0);//O_NONBLOCK);
|
||||
|
||||
return Connection::createShared(handle);
|
||||
|
||||
}
|
||||
|
||||
}}}
|
59
network/src/server/SimpleTCPConnectionProvider.hpp
Normal file
59
network/src/server/SimpleTCPConnectionProvider.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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_netword_server_SimpleTCPConnectionProvider_hpp
|
||||
#define oatpp_netword_server_SimpleTCPConnectionProvider_hpp
|
||||
|
||||
#include "../ConnectionProvider.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/data/stream/Stream.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/base/String.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/os/io/Library.hpp"
|
||||
|
||||
namespace oatpp { namespace network { namespace server {
|
||||
|
||||
class SimpleTCPConnectionProvider : public base::Controllable, public ServerConnectionProvider {
|
||||
private:
|
||||
oatpp::os::io::Library::v_handle m_serverHandle;
|
||||
private:
|
||||
oatpp::os::io::Library::v_handle instantiateServer();
|
||||
public:
|
||||
SimpleTCPConnectionProvider(v_word16 port)
|
||||
: ServerConnectionProvider(port)
|
||||
{
|
||||
m_serverHandle = instantiateServer();
|
||||
}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<SimpleTCPConnectionProvider> createShared(v_word16 port){
|
||||
return std::shared_ptr<SimpleTCPConnectionProvider>(new SimpleTCPConnectionProvider(port));
|
||||
}
|
||||
|
||||
std::shared_ptr<IOStream> getConnection() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_netword_server_SimpleTCPConnectionProvider_hpp */
|
443
parser/src/json/Utils.cpp
Normal file
443
parser/src/json/Utils.cpp
Normal file
@ -0,0 +1,443 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "Utils.hpp"
|
||||
|
||||
#include "../../../../oatpp-lib/encoding/src/Unicode.hpp"
|
||||
#include "../../../../oatpp-lib/encoding/src/Hex.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json{
|
||||
|
||||
const char* const Utils::ERROR_INVALID_ESCAPED_CHAR = "ERROR_INVALID_ESCAPED_CHAR";
|
||||
const char* const Utils::ERROR_INVALID_SURROGATE_PAIR = "ERROR_INVALID_SURROGATE_PAIR";
|
||||
const char* const Utils::ERROR_PARSER_QUOTE_EXPECTED = "'\"' - EXPECTED";
|
||||
|
||||
v_int32 Utils::calcEscapedStringSize(p_char8 data, v_int32 size, v_int32& safeSize) {
|
||||
v_int32 result = 0;
|
||||
v_int32 i = 0;
|
||||
safeSize = size;
|
||||
while (i < size) {
|
||||
v_char8 a = data[i];
|
||||
if(a < 32) {
|
||||
i ++;
|
||||
if(a == '\b' || a == '\f' || a == '\n' || a == '\r' || a == '\t'){
|
||||
result += 2; // '\n'
|
||||
} else {
|
||||
result += 6; // '\uFFFF' - 6 chars
|
||||
}
|
||||
} else if(a < 128){
|
||||
i ++;
|
||||
if(a == '\"' || a == '\\' || a == '/'){
|
||||
result += 2; // '\/'
|
||||
} else {
|
||||
result ++;
|
||||
}
|
||||
} else {
|
||||
v_int32 charSize = oatpp::encoding::Unicode::getUtf8CharSequenceLength(a);
|
||||
if(charSize != 0) {
|
||||
if(i + charSize > size) {
|
||||
safeSize = i;
|
||||
}
|
||||
i += charSize;
|
||||
if(charSize < 4) {
|
||||
result += 6; // '\uFFFF' - 6 chars
|
||||
} else if(charSize == 4) {
|
||||
result += 12; // '\uFFFF\uFFFF' - 12 chars surrogate pair
|
||||
} else {
|
||||
result += 11; // '\u+FFFFFFFF' - 11 chars NOT JSON standard case
|
||||
}
|
||||
} else {
|
||||
// invalid char
|
||||
i ++;
|
||||
result ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
v_int32 Utils::calcUnescapedStringSize(p_char8 data, v_int32 size, const char* & error, v_int32& errorPosition) {
|
||||
error = nullptr;
|
||||
v_int32 result = 0;
|
||||
v_int32 i = 0;
|
||||
|
||||
while (i < size) {
|
||||
v_char8 a = data[i];
|
||||
if(a == '\\'){
|
||||
|
||||
if(i + 1 == size){
|
||||
error = ERROR_INVALID_ESCAPED_CHAR;
|
||||
errorPosition = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
v_char8 b = data[i + 1];
|
||||
|
||||
if(b == '"' || b == '\\' || b == '/' || b == 'b' || b == 'f' || b == 'n' || b == 'r' || b == 't'){
|
||||
result += 1;
|
||||
i += 2;
|
||||
} else if(b == 'u'){
|
||||
|
||||
if(i + 6 > size){
|
||||
error = ERROR_INVALID_ESCAPED_CHAR;
|
||||
errorPosition = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(data[i + 2] == '+') { // not JSON standard case
|
||||
if(i + 11 > size){
|
||||
error = ERROR_INVALID_ESCAPED_CHAR;
|
||||
errorPosition = i;
|
||||
return 0;
|
||||
}
|
||||
v_word32 code;
|
||||
error = encoding::Hex::readWord32(&data[i + 3], code);
|
||||
if(error != nullptr){
|
||||
errorPosition = i + 3;
|
||||
return 0;
|
||||
}
|
||||
i += 11;
|
||||
result += encoding::Unicode::getUtf8CharSequenceLengthForCode(code);
|
||||
} else {
|
||||
v_word16 code;
|
||||
error = encoding::Hex::readWord16(&data[i + 2], code);
|
||||
if(error != nullptr){
|
||||
errorPosition = i + 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(code >= 0xD800 && code <= 0xDBFF){
|
||||
if(i + 12 > size){
|
||||
error = ERROR_INVALID_SURROGATE_PAIR;
|
||||
errorPosition = i;
|
||||
return 0;
|
||||
}
|
||||
v_word16 low;
|
||||
error = encoding::Hex::readWord16(&data[i + 8], low);
|
||||
if(error != nullptr){
|
||||
errorPosition = i + 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(low >= 0xDC00 && low <= 0xDFFF){
|
||||
v_word32 bigCode = encoding::Unicode::utf16SurrogatePairToCode(code, low);
|
||||
i += 12;
|
||||
result += encoding::Unicode::getUtf8CharSequenceLengthForCode(bigCode);
|
||||
} else {
|
||||
error = ERROR_INVALID_SURROGATE_PAIR;
|
||||
errorPosition = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
i += 6;
|
||||
result += encoding::Unicode::getUtf8CharSequenceLengthForCode(code);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
error = ERROR_INVALID_ESCAPED_CHAR;
|
||||
errorPosition = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
i ++;
|
||||
result ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
v_int32 Utils::escapeUtf8Char(p_char8 sequence, p_char8 buffer){
|
||||
v_int32 length;
|
||||
v_int32 code = oatpp::encoding::Unicode::encodeUtf8Char(sequence, length);
|
||||
if(code < 0x00010000) {
|
||||
buffer[0] = '\\';
|
||||
buffer[1] = 'u';
|
||||
oatpp::encoding::Hex::writeWord16(code, &buffer[2]);
|
||||
return 6;
|
||||
} else if(code < 0x00200000) {
|
||||
v_int16 high;
|
||||
v_int16 low;
|
||||
oatpp::encoding::Unicode::codeToUtf16SurrogatePair(code, high, low);
|
||||
buffer[0] = '\\';
|
||||
buffer[1] = 'u';
|
||||
oatpp::encoding::Hex::writeWord16(high, &buffer[2]);
|
||||
buffer[6] = '\\';
|
||||
buffer[7] = 'u';
|
||||
oatpp::encoding::Hex::writeWord16(low, &buffer[8]);
|
||||
return 12;
|
||||
} else {
|
||||
buffer[0] = '\\';
|
||||
buffer[1] = 'u';
|
||||
buffer[2] = '+';
|
||||
oatpp::encoding::Hex::writeWord32(code, &buffer[2]);
|
||||
return 11;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Utils::String> Utils::escapeString(p_char8 data, v_int32 size) {
|
||||
v_int32 safeSize;
|
||||
v_int32 escapedSize = calcEscapedStringSize(data, size, safeSize);
|
||||
if(escapedSize == size) {
|
||||
return String::createShared(data, size, true);
|
||||
}
|
||||
auto result = String::createShared(escapedSize);
|
||||
v_int32 i = 0;
|
||||
p_char8 resultData = result->getData();
|
||||
v_int32 pos = 0;
|
||||
|
||||
while (i < safeSize) {
|
||||
v_char8 a = data[i];
|
||||
if(a < 32) {
|
||||
if(a == '\b'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = 'b'; pos += 2;
|
||||
} else if(a == '\f'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = 'f'; pos += 2;
|
||||
} else if(a == '\n'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = 'n'; pos += 2;
|
||||
} else if(a == '\r'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = 'r'; pos += 2;
|
||||
} else if(a == '\t'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = 't'; pos += 2;
|
||||
} else {
|
||||
resultData[pos] = '\\';
|
||||
resultData[pos + 1] = 'u';
|
||||
oatpp::encoding::Hex::writeWord16(a, &resultData[pos + 2]);
|
||||
pos += 6;
|
||||
}
|
||||
i ++;
|
||||
} else if(a < 128){
|
||||
if(a == '\"'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = '"'; pos += 2;
|
||||
} else if(a == '\\'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = '\\'; pos += 2;
|
||||
} else if(a == '/'){
|
||||
resultData[pos] = '\\'; resultData[pos + 1] = '/'; pos += 2;
|
||||
} else {
|
||||
resultData[pos] = data[i];
|
||||
pos ++;
|
||||
}
|
||||
i ++;
|
||||
} else {
|
||||
v_int32 charSize = oatpp::encoding::Unicode::getUtf8CharSequenceLength(a);
|
||||
if(charSize != 0) {
|
||||
pos += escapeUtf8Char(&data[i], &resultData[pos]);
|
||||
i += charSize;
|
||||
} else {
|
||||
// invalid char
|
||||
resultData[pos] = data[i];
|
||||
i ++;
|
||||
pos ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(size > safeSize){
|
||||
for(v_int32 i = pos; i < result->getSize(); i ++){
|
||||
resultData[i] = '?';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Utils::unescapeStringToBuffer(p_char8 data, v_int32 size, p_char8 resultData){
|
||||
|
||||
v_int32 i = 0;
|
||||
v_int32 pos = 0;
|
||||
|
||||
while (i < size) {
|
||||
v_char8 a = data[i];
|
||||
|
||||
if(a == '\\'){
|
||||
v_char8 b = data[i + 1];
|
||||
if(b != 'u'){
|
||||
switch (b) {
|
||||
case '"': resultData[pos] = '"'; pos ++; break;
|
||||
case '\\': resultData[pos] = '\\'; pos ++; break;
|
||||
case '/': resultData[pos] = '/'; pos ++; break;
|
||||
case 'b': resultData[pos] = '\b'; pos ++; break;
|
||||
case 'f': resultData[pos] = '\f'; pos ++; break;
|
||||
case 'n': resultData[pos] = '\n'; pos ++; break;
|
||||
case 'r': resultData[pos] = '\r'; pos ++; break;
|
||||
case 't': resultData[pos] = '\t'; pos ++; break;
|
||||
}
|
||||
i += 2;
|
||||
} else {
|
||||
if(data[i + 2] == '+'){ // Not JSON standard case
|
||||
v_word32 code;
|
||||
encoding::Hex::readWord32(&data[i + 3], code);
|
||||
i += 11;
|
||||
pos += encoding::Unicode::decodeUtf8Char(code, &resultData[pos]);
|
||||
} else {
|
||||
|
||||
v_word16 code;
|
||||
encoding::Hex::readWord16(&data[i + 2], code);
|
||||
|
||||
if(code >= 0xD800 && code <= 0xDBFF){
|
||||
v_word16 low;
|
||||
encoding::Hex::readWord16(&data[i + 8], low);
|
||||
v_word32 bigCode = encoding::Unicode::utf16SurrogatePairToCode(code, low);
|
||||
pos += encoding::Unicode::decodeUtf8Char(bigCode, &resultData[pos]);
|
||||
i += 12;
|
||||
} else {
|
||||
pos += encoding::Unicode::decodeUtf8Char(code, &resultData[pos]);
|
||||
i += 6;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resultData[pos] = a;
|
||||
pos ++;
|
||||
i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Utils::String> Utils::unescapeString(p_char8 data, v_int32 size,
|
||||
const char* & error, v_int32& errorPosition) {
|
||||
|
||||
v_int32 unescapedSize = calcUnescapedStringSize(data, size, error, errorPosition);
|
||||
if(error != nullptr){
|
||||
return nullptr;
|
||||
}
|
||||
auto result = String::createShared(unescapedSize);
|
||||
if(unescapedSize == size) {
|
||||
std::memcpy(result->getData(), data, size);
|
||||
} else {
|
||||
unescapeStringToBuffer(data, size, result->getData());
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
std::string Utils::unescapeStringToStdString(p_char8 data, v_int32 size,
|
||||
const char* & error, v_int32& errorPosition){
|
||||
v_int32 unescapedSize = calcUnescapedStringSize(data, size, error, errorPosition);
|
||||
if(error != nullptr){
|
||||
return "";
|
||||
}
|
||||
std::string result;
|
||||
result.resize(unescapedSize);
|
||||
if(unescapedSize == size) {
|
||||
std::memcpy((p_char8) result.data(), data, size);
|
||||
} else {
|
||||
unescapeStringToBuffer(data, size, (p_char8) result.data());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
p_char8 Utils::preparseString(const std::shared_ptr<ParsingCaret>& caret, v_int32& size){
|
||||
|
||||
if(caret->canContinueAtChar('"', 1)){
|
||||
|
||||
const p_char8 data = caret->getData();
|
||||
v_int32 pos = caret->getPosition();
|
||||
v_int32 pos0 = pos;
|
||||
v_int32 length = caret->getSize();
|
||||
|
||||
while (pos < length) {
|
||||
v_char8 a = data[pos];
|
||||
if(a == '"'){
|
||||
size = pos - pos0;
|
||||
return &data[pos0];
|
||||
} else if(a == '\\') {
|
||||
pos += 2;
|
||||
} else {
|
||||
pos ++;
|
||||
}
|
||||
}
|
||||
caret->setPosition(caret->getSize());
|
||||
caret->setError(ERROR_PARSER_QUOTE_EXPECTED);
|
||||
} else {
|
||||
caret->setError(ERROR_PARSER_QUOTE_EXPECTED);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Utils::String> Utils::parseString(const std::shared_ptr<ParsingCaret>& caret) {
|
||||
|
||||
v_int32 size;
|
||||
p_char8 data = preparseString(caret, size);
|
||||
|
||||
if(data != nullptr) {
|
||||
|
||||
v_int32 pos = caret->getPosition();
|
||||
|
||||
const char* error;
|
||||
v_int32 errorPosition;
|
||||
auto result = unescapeString(data, size, error, errorPosition);
|
||||
if(error != nullptr){
|
||||
caret->setError(error);
|
||||
caret->setPosition(pos + errorPosition);
|
||||
} else {
|
||||
caret->setPosition(pos + size + 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
std::string Utils::parseStringToStdString(const std::shared_ptr<ParsingCaret>& caret){
|
||||
|
||||
v_int32 size;
|
||||
p_char8 data = preparseString(caret, size);
|
||||
|
||||
if(data != nullptr) {
|
||||
|
||||
v_int32 pos = caret->getPosition();
|
||||
|
||||
const char* error;
|
||||
v_int32 errorPosition;
|
||||
const std::string& result = unescapeStringToStdString(data, size, error, errorPosition);
|
||||
if(error != nullptr){
|
||||
caret->setError(error);
|
||||
caret->setPosition(pos + errorPosition);
|
||||
} else {
|
||||
caret->setPosition(pos + size + 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
|
||||
}}}
|
64
parser/src/json/Utils.hpp
Normal file
64
parser/src/json/Utils.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_parser_json_Utils_hpp
|
||||
#define oatpp_parser_json_Utils_hpp
|
||||
|
||||
#include "../../../../oatpp-lib/core/src/parser/ParsingCaret.hpp"
|
||||
#include "../../../../oatpp-lib/core/src/base/String.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace oatpp { namespace parser { namespace json{
|
||||
|
||||
class Utils {
|
||||
public:
|
||||
static const char* const ERROR_INVALID_ESCAPED_CHAR;
|
||||
static const char* const ERROR_INVALID_SURROGATE_PAIR;
|
||||
|
||||
static const char* const ERROR_PARSER_QUOTE_EXPECTED;
|
||||
public:
|
||||
typedef oatpp::base::String String;
|
||||
typedef oatpp::parser::ParsingCaret ParsingCaret;
|
||||
private:
|
||||
static v_int32 escapeUtf8Char(p_char8 sequence, p_char8 buffer);
|
||||
static v_int32 calcEscapedStringSize(p_char8 data, v_int32 size, v_int32& safeSize);
|
||||
static v_int32 calcUnescapedStringSize(p_char8 data, v_int32 size, const char* & error, v_int32& errorPosition);
|
||||
static void unescapeStringToBuffer(p_char8 data, v_int32 size, p_char8 resultData);
|
||||
static p_char8 preparseString(const std::shared_ptr<ParsingCaret>& caret, v_int32& size);
|
||||
public:
|
||||
|
||||
static std::shared_ptr<String> escapeString(p_char8 data, v_int32 size);
|
||||
static std::shared_ptr<String> unescapeString(p_char8 data, v_int32 size, const char* & error, v_int32& errorPosition);
|
||||
static std::string unescapeStringToStdString(p_char8 data, v_int32 size,
|
||||
const char* & error, v_int32& errorPosition);
|
||||
|
||||
static std::shared_ptr<String> parseString(const std::shared_ptr<ParsingCaret>& caret);
|
||||
static std::string parseStringToStdString(const std::shared_ptr<ParsingCaret>& caret);
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_parser_json_Utils_hpp */
|
325
parser/src/json/mapping/Deserializer.cpp
Normal file
325
parser/src/json/mapping/Deserializer.cpp
Normal file
@ -0,0 +1,325 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Deserializer.hpp"
|
||||
|
||||
#include "../Utils.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/utils/ConversionUtils.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
const char* const Deserializer::ERROR_PARSER_OBJECT_SCOPE_OPEN = "'{' - expected";
|
||||
const char* const Deserializer::ERROR_PARSER_OBJECT_SCOPE_CLOSE = "'}' - expected";
|
||||
const char* const Deserializer::ERROR_PARSER_OBJECT_SCOPE_UNKNOWN_FIELD = "Unknown field";
|
||||
const char* const Deserializer::ERROR_PARSER_OBJECT_SCOPE_COLON_MISSING = "':' - expected";
|
||||
const char* const Deserializer::ERROR_PARSER_ARRAY_SCOPE_OPEN = "'[' - expected";
|
||||
const char* const Deserializer::ERROR_PARSER_ARRAY_SCOPE_CLOSE = "']' - expected";
|
||||
|
||||
void Deserializer::skipScope(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret, v_char8 charOpen, v_char8 charClose){
|
||||
|
||||
p_char8 data = caret->getData();
|
||||
v_int32 size = caret->getSize();
|
||||
v_int32 pos = caret->getPosition();
|
||||
v_int32 scopeCounter = 0;
|
||||
|
||||
bool isInString = false;
|
||||
|
||||
while(pos < size){
|
||||
v_char8 a = data[pos];
|
||||
if(a == charOpen){
|
||||
if(!isInString){
|
||||
scopeCounter ++;
|
||||
}
|
||||
} else if(a == charClose){
|
||||
if(!isInString){
|
||||
scopeCounter --;
|
||||
if(scopeCounter == 0){
|
||||
caret->setPosition(pos + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if(a == '"') {
|
||||
isInString = !isInString;
|
||||
} else if(a == '\\'){
|
||||
pos ++;
|
||||
}
|
||||
|
||||
pos ++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Deserializer::skipString(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
p_char8 data = caret->getData();
|
||||
v_int32 size = caret->getSize();
|
||||
v_int32 pos = caret->getPosition();
|
||||
v_int32 scopeCounter = 0;
|
||||
while(pos < size){
|
||||
v_char8 a = data[pos];
|
||||
if(a == '"'){
|
||||
scopeCounter ++;
|
||||
if(scopeCounter == 2) {
|
||||
caret->setPosition(pos + 1);
|
||||
return;
|
||||
}
|
||||
} else if(a == '\\'){
|
||||
pos ++;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
}
|
||||
|
||||
void Deserializer::skipToken(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
p_char8 data = caret->getData();
|
||||
v_int32 size = caret->getSize();
|
||||
v_int32 pos = caret->getPosition();
|
||||
while(pos < size){
|
||||
v_char8 a = data[pos];
|
||||
if(a == ' ' || a == '\t' || a == '\n' || a == '\r' || a == '\b' || a == '\f' ||
|
||||
a == '}' || a == ',' || a == ']') {
|
||||
caret->setPosition(pos);
|
||||
return;
|
||||
}
|
||||
pos ++;
|
||||
}
|
||||
}
|
||||
|
||||
void Deserializer::skipValue(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->isAtChar('{')){
|
||||
skipScope(caret, '{', '}');
|
||||
} else if(caret->isAtChar('[')){
|
||||
skipScope(caret, '[', ']');
|
||||
} else if(caret->isAtChar('"')){
|
||||
skipString(caret);
|
||||
} else {
|
||||
skipToken(caret);
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readStringValue(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper(String::Class::getType());
|
||||
} else {
|
||||
return AbstractSharedWrapper(oatpp::parser::json::Utils::parseString(caret), String::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readInt32Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper(Int32::SharedWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractSharedWrapper(Int32::createAbstract(caret->parseInt32()), Int32::SharedWrapper::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readInt64Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper(Int64::SharedWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractSharedWrapper(Int64::createAbstract(caret->parseInt64()), Int64::SharedWrapper::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readFloat32Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper(Float32::SharedWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractSharedWrapper(Float32::createAbstract(caret->parseFloat32()), Float32::SharedWrapper::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readFloat64Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper(Float64::SharedWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractSharedWrapper(Float64::createAbstract(caret->parseFloat64()), Float64::SharedWrapper::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readBooleanValue(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper(Boolean::SharedWrapper::Class::getType());
|
||||
} else {
|
||||
return AbstractSharedWrapper(Boolean::createAbstract(caret->parseBoolean("true", "false")), Boolean::SharedWrapper::Class::getType());
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readObjectValue(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper::empty();
|
||||
} else {
|
||||
return readObject(type, caret, config);
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readListValue(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config){
|
||||
if(caret->proceedIfFollowsText("null")){
|
||||
return AbstractSharedWrapper::empty();
|
||||
} else {
|
||||
return readList(type, caret, config);
|
||||
}
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readValue(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config){
|
||||
|
||||
auto typeName = type->name;
|
||||
if(typeName == oatpp::data::mapping::type::__class::String::CLASS_NAME){
|
||||
return readStringValue(caret);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Int32::CLASS_NAME){
|
||||
return readInt32Value(caret);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Int64::CLASS_NAME){
|
||||
return readInt64Value(caret);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Float32::CLASS_NAME){
|
||||
return readFloat32Value(caret);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Float64::CLASS_NAME){
|
||||
return readFloat64Value(caret);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Boolean::CLASS_NAME){
|
||||
return readBooleanValue(caret);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME){
|
||||
return readObjectValue(type, caret, config);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME){
|
||||
return readListValue(type, caret, config);
|
||||
} else {
|
||||
skipValue(caret);
|
||||
}
|
||||
|
||||
return AbstractSharedWrapper::empty();
|
||||
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readList(const Type* type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config){
|
||||
|
||||
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();
|
||||
|
||||
while(!caret->isAtChar(']') && caret->canContinue()){
|
||||
|
||||
caret->findNotBlankChar();
|
||||
auto item = readValue(itemType, caret, config);
|
||||
if(caret->hasError()){
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
list->addPolymorphicItem(item);
|
||||
caret->findNotBlankChar();
|
||||
|
||||
caret->canContinueAtChar(',', 1);
|
||||
|
||||
}
|
||||
|
||||
if(!caret->canContinueAtChar(']', 1)){
|
||||
if(!caret->hasError()){
|
||||
caret->setError(ERROR_PARSER_ARRAY_SCOPE_CLOSE);
|
||||
}
|
||||
return AbstractSharedWrapper::empty();
|
||||
};
|
||||
|
||||
return AbstractSharedWrapper(list.getPtr(), list.valueType);
|
||||
} else {
|
||||
caret->setError(ERROR_PARSER_ARRAY_SCOPE_OPEN);
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Deserializer::AbstractSharedWrapper Deserializer::readObject(const Type* type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config){
|
||||
|
||||
if(caret->canContinueAtChar('{', 1)) {
|
||||
|
||||
auto object = type->creator();
|
||||
auto fieldsMap = type->properties;
|
||||
|
||||
while (!caret->isAtChar('}') && caret->canContinue()) {
|
||||
|
||||
caret->findNotBlankChar();
|
||||
auto key = Utils::parseStringToStdString(caret);
|
||||
if(caret->hasError()){
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
auto fieldIterator = fieldsMap->find(key);
|
||||
if(fieldIterator != fieldsMap->end()){
|
||||
|
||||
caret->findNotBlankChar();
|
||||
if(!caret->canContinueAtChar(':', 1)){
|
||||
caret->setError(ERROR_PARSER_OBJECT_SCOPE_COLON_MISSING);
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
caret->findNotBlankChar();
|
||||
|
||||
auto field = fieldIterator->second;
|
||||
field->set(object.get(), readValue(field->type, caret, config));
|
||||
|
||||
} else if (config->allowUnknownFields) {
|
||||
caret->findNotBlankChar();
|
||||
if(!caret->canContinueAtChar(':', 1)){
|
||||
caret->setError(ERROR_PARSER_OBJECT_SCOPE_COLON_MISSING);
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
caret->findNotBlankChar();
|
||||
skipValue(caret);
|
||||
} else {
|
||||
caret->setError(ERROR_PARSER_OBJECT_SCOPE_UNKNOWN_FIELD);
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
caret->findNotBlankChar();
|
||||
caret->canContinueAtChar(',', 1);
|
||||
|
||||
};
|
||||
|
||||
if(!caret->canContinueAtChar('}', 1)){
|
||||
if(!caret->hasError()){
|
||||
caret->setError(ERROR_PARSER_OBJECT_SCOPE_CLOSE);
|
||||
}
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
return object;
|
||||
|
||||
} else {
|
||||
caret->setError(ERROR_PARSER_OBJECT_SCOPE_OPEN);
|
||||
}
|
||||
|
||||
return AbstractSharedWrapper::empty();
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
131
parser/src/json/mapping/Deserializer.hpp
Normal file
131
parser/src/json/mapping/Deserializer.hpp
Normal file
@ -0,0 +1,131 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_parser_json_mapping_Deserializer_hpp
|
||||
#define oatpp_parser_json_mapping_Deserializer_hpp
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/List.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Object.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Primitive.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Type.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/parser/ParsingCaret.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/collection/LinkedList.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/base/String.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
class Deserializer {
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::Type Type;
|
||||
typedef oatpp::data::mapping::type::Type::Property Property;
|
||||
typedef oatpp::data::mapping::type::Type::Properties Properties;
|
||||
|
||||
typedef oatpp::data::mapping::type::AbstractSharedWrapper AbstractSharedWrapper;
|
||||
typedef oatpp::data::mapping::type::Object Object;
|
||||
|
||||
private:
|
||||
typedef oatpp::data::mapping::type::StringSharedWrapper String;
|
||||
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;
|
||||
|
||||
typedef oatpp::data::mapping::type::List<AbstractSharedWrapper> AbstractList;
|
||||
|
||||
public:
|
||||
|
||||
class Config : public oatpp::base::Controllable {
|
||||
public:
|
||||
Config()
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<Config> createShared(){
|
||||
return std::shared_ptr<Config>(new Config());
|
||||
}
|
||||
|
||||
bool allowUnknownFields = true;
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
static const char* const ERROR_PARSER_OBJECT_SCOPE_OPEN;
|
||||
static const char* const ERROR_PARSER_OBJECT_SCOPE_CLOSE;
|
||||
static const char* const ERROR_PARSER_OBJECT_SCOPE_UNKNOWN_FIELD;
|
||||
static const char* const ERROR_PARSER_OBJECT_SCOPE_COLON_MISSING;
|
||||
static const char* const ERROR_PARSER_ARRAY_SCOPE_OPEN;
|
||||
static const char* const ERROR_PARSER_ARRAY_SCOPE_CLOSE;
|
||||
private:
|
||||
|
||||
static void skipScope(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret, v_char8 charOpen, v_char8 charClose);
|
||||
static void skipString(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static void skipToken(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static void skipValue(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
|
||||
static AbstractSharedWrapper readStringValue(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static AbstractSharedWrapper readInt32Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static AbstractSharedWrapper readInt64Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static AbstractSharedWrapper readFloat32Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static AbstractSharedWrapper readFloat64Value(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static AbstractSharedWrapper readBooleanValue(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret);
|
||||
static AbstractSharedWrapper readObjectValue(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config);
|
||||
static AbstractSharedWrapper readListValue(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config);
|
||||
|
||||
static AbstractSharedWrapper readValue(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config);
|
||||
|
||||
static AbstractSharedWrapper readList(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config);
|
||||
|
||||
static AbstractSharedWrapper readObject(const Type* const type,
|
||||
const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config);
|
||||
|
||||
public:
|
||||
|
||||
static AbstractSharedWrapper deserialize(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const std::shared_ptr<Config>& config,
|
||||
const Type* const type) {
|
||||
if(type->name == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME){
|
||||
return readObject(type, caret, config);
|
||||
} else if(type->name == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME){
|
||||
return readList(type, caret, config);
|
||||
}
|
||||
return AbstractSharedWrapper::empty();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_parser_json_mapping_Deserializer_hpp */
|
26
parser/src/json/mapping/ObjectMapper.cpp
Normal file
26
parser/src/json/mapping/ObjectMapper.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "ObjectMapper.hpp"
|
||||
|
74
parser/src/json/mapping/ObjectMapper.hpp
Normal file
74
parser/src/json/mapping/ObjectMapper.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_parser_json_mapping_ObjectMapper_hpp
|
||||
#define oatpp_parser_json_mapping_ObjectMapper_hpp
|
||||
|
||||
#include "./Serializer.hpp"
|
||||
#include "./Deserializer.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/ObjectMapper.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
class ObjectMapper : public oatpp::base::Controllable, public oatpp::data::mapping::ObjectMapper {
|
||||
private:
|
||||
static Info& getMapperInfo(){
|
||||
static Info info("application/json");
|
||||
return info;
|
||||
}
|
||||
public:
|
||||
ObjectMapper(const std::shared_ptr<Serializer::Config>& pSerializerConfig,
|
||||
const std::shared_ptr<Deserializer::Config>& pDeserializerConfig)
|
||||
: oatpp::data::mapping::ObjectMapper(getMapperInfo())
|
||||
, serializerConfig(pSerializerConfig)
|
||||
, deserializerConfig(pDeserializerConfig)
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<ObjectMapper>
|
||||
createShared(const std::shared_ptr<Serializer::Config>& serializerConfig = Serializer::Config::createShared(),
|
||||
const std::shared_ptr<Deserializer::Config>& deserializerConfig = Deserializer::Config::createShared()){
|
||||
return std::shared_ptr<ObjectMapper>(new ObjectMapper(serializerConfig, deserializerConfig));
|
||||
}
|
||||
|
||||
void write(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
|
||||
const oatpp::data::mapping::type::VariantWrapper& variant) override {
|
||||
Serializer::serialize(stream, variant);
|
||||
}
|
||||
|
||||
oatpp::data::mapping::type::AbstractSharedWrapper
|
||||
read(const std::shared_ptr<oatpp::parser::ParsingCaret>& caret,
|
||||
const oatpp::data::mapping::type::Type* const type) override {
|
||||
return Deserializer::deserialize(caret, deserializerConfig, type);
|
||||
}
|
||||
|
||||
std::shared_ptr<Serializer::Config> serializerConfig;
|
||||
std::shared_ptr<Deserializer::Config> deserializerConfig;
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_parser_json_mapping_ObjectMapper_hpp */
|
238
parser/src/json/mapping/Serializer.cpp
Normal file
238
parser/src/json/mapping/Serializer.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "./Serializer.hpp"
|
||||
|
||||
#include "../Utils.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
void Serializer::writeString(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field) {
|
||||
auto value = oatpp::base::static_wrapper_cast<String>(field->get(object));
|
||||
stream->writeChar('\"');
|
||||
stream->write(field->name);
|
||||
stream->write("\": ", 3);
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
auto encodedValue = Utils::escapeString(value->getData(), value->getSize());
|
||||
stream->writeChar('\"');
|
||||
stream->write(encodedValue);
|
||||
stream->writeChar('\"');
|
||||
}
|
||||
}
|
||||
|
||||
void Serializer::writeObject(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field){
|
||||
|
||||
auto value = oatpp::base::static_wrapper_cast<Object>(field->get(object));
|
||||
stream->writeChar('\"');
|
||||
stream->write(field->name);
|
||||
stream->write("\": ", 3);
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
writeObject(stream, field->type, value.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Serializer::writeListOfString(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list){
|
||||
stream->writeChar('[');
|
||||
bool first = true;
|
||||
auto curr = list->getFirstNode();
|
||||
while(curr != nullptr){
|
||||
|
||||
auto value = oatpp::base::static_wrapper_cast<String>(curr->getData());
|
||||
|
||||
if(first){
|
||||
first = false;
|
||||
} else {
|
||||
stream->write(", ", 2);
|
||||
}
|
||||
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
auto encodedValue = Utils::escapeString(value->getData(), value->getSize());
|
||||
stream->writeChar('\"');
|
||||
stream->write(encodedValue);
|
||||
stream->writeChar('\"');
|
||||
}
|
||||
|
||||
curr = curr->getNext();
|
||||
}
|
||||
|
||||
stream->writeChar(']');
|
||||
|
||||
}
|
||||
|
||||
void Serializer::writeListOfObject(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list,
|
||||
const Type* const type){
|
||||
stream->writeChar('[');
|
||||
bool first = true;
|
||||
auto curr = list->getFirstNode();
|
||||
while(curr != nullptr){
|
||||
|
||||
auto value = oatpp::base::static_wrapper_cast<Object>(curr->getData());
|
||||
|
||||
if(first){
|
||||
first = false;
|
||||
} else {
|
||||
stream->write(", ", 2);
|
||||
}
|
||||
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
writeObject(stream, type, value.get());
|
||||
}
|
||||
|
||||
curr = curr->getNext();
|
||||
}
|
||||
|
||||
stream->writeChar(']');
|
||||
|
||||
}
|
||||
|
||||
void Serializer::writeListOfList(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list,
|
||||
const Type* const type){
|
||||
stream->writeChar('[');
|
||||
bool first = true;
|
||||
auto curr = list->getFirstNode();
|
||||
while(curr != nullptr){
|
||||
|
||||
auto value = oatpp::base::static_wrapper_cast<AbstractList>(curr->getData());
|
||||
|
||||
if(first){
|
||||
first = false;
|
||||
} else {
|
||||
stream->write(", ", 2);
|
||||
}
|
||||
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
writeListCollection(stream, value.get(), type);
|
||||
}
|
||||
|
||||
curr = curr->getNext();
|
||||
}
|
||||
|
||||
stream->writeChar(']');
|
||||
|
||||
}
|
||||
|
||||
void Serializer::writeListCollection(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list,
|
||||
const Type* const type){
|
||||
|
||||
Type* itemType = *(type->params.begin());
|
||||
auto itemTypeName = itemType->name;
|
||||
|
||||
if(itemTypeName == oatpp::data::mapping::type::__class::String::CLASS_NAME){
|
||||
writeListOfString(stream, list);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::Int32::CLASS_NAME) {
|
||||
writeListOfSimpleData<oatpp::data::mapping::type::Int32>(stream, list);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::Int64::CLASS_NAME) {
|
||||
writeListOfSimpleData<oatpp::data::mapping::type::Int64>(stream, list);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::Float32::CLASS_NAME) {
|
||||
writeListOfSimpleData<oatpp::data::mapping::type::Float32>(stream, list);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::Float64::CLASS_NAME) {
|
||||
writeListOfSimpleData<oatpp::data::mapping::type::Float64>(stream, list);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::Boolean::CLASS_NAME) {
|
||||
writeListOfSimpleData<oatpp::data::mapping::type::Boolean>(stream, list);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME) {
|
||||
writeListOfObject(stream, list, itemType);
|
||||
} else if(itemTypeName == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME) {
|
||||
writeListOfList(stream, list, itemType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Serializer::writeList(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field){
|
||||
auto value = oatpp::base::static_wrapper_cast<AbstractList>(field->get(object));
|
||||
stream->writeChar('\"');
|
||||
stream->write(field->name);
|
||||
stream->write("\": ", 3);
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
writeListCollection(stream, value.get(), field->type);
|
||||
}
|
||||
}
|
||||
|
||||
void Serializer::writeObject(oatpp::data::stream::OutputStream* stream,
|
||||
const Type* type,
|
||||
Object* object){
|
||||
|
||||
stream->writeChar('{');
|
||||
bool firstField = true;
|
||||
auto fieldsMap = type->properties;
|
||||
for (auto const& iterator : *fieldsMap) {
|
||||
|
||||
auto field = iterator.second;
|
||||
|
||||
if(firstField){
|
||||
firstField = false;
|
||||
} else {
|
||||
stream->write(", ", 2);
|
||||
}
|
||||
|
||||
auto type = field->type;
|
||||
auto typeName = type->name;
|
||||
|
||||
if(typeName == oatpp::data::mapping::type::__class::String::CLASS_NAME){
|
||||
writeString(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Int32::CLASS_NAME) {
|
||||
writeSimpleData<oatpp::data::mapping::type::Int32>(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Int64::CLASS_NAME) {
|
||||
writeSimpleData<oatpp::data::mapping::type::Int64>(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Float32::CLASS_NAME) {
|
||||
writeSimpleData<oatpp::data::mapping::type::Float32>(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Float64::CLASS_NAME) {
|
||||
writeSimpleData<oatpp::data::mapping::type::Float64>(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::Boolean::CLASS_NAME) {
|
||||
writeSimpleData<oatpp::data::mapping::type::Boolean>(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME) {
|
||||
writeObject(stream, object, field);
|
||||
} else if(typeName == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME) {
|
||||
writeList(stream, object, field);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
stream->writeChar('}');
|
||||
|
||||
}
|
||||
|
||||
}}}}
|
163
parser/src/json/mapping/Serializer.hpp
Normal file
163
parser/src/json/mapping/Serializer.hpp
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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_parser_json_mapping_Serializer_hpp
|
||||
#define oatpp_parser_json_mapping_Serializer_hpp
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/List.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Object.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Primitive.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Type.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/stream/ChunkedBuffer.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/parser/ParsingCaret.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/collection/LinkedList.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/base/String.hpp"
|
||||
|
||||
namespace oatpp { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
class Serializer {
|
||||
public:
|
||||
typedef oatpp::data::mapping::type::Type Type;
|
||||
typedef oatpp::data::mapping::type::Type::Property Property;
|
||||
typedef oatpp::data::mapping::type::Type::Properties Properties;
|
||||
|
||||
typedef oatpp::data::mapping::type::Object Object;
|
||||
|
||||
typedef oatpp::data::mapping::type::List<
|
||||
oatpp::data::mapping::type::AbstractSharedWrapper
|
||||
> AbstractList;
|
||||
public:
|
||||
|
||||
class Config : public oatpp::base::Controllable {
|
||||
protected:
|
||||
Config()
|
||||
{}
|
||||
public:
|
||||
|
||||
static std::shared_ptr<Config> createShared(){
|
||||
return std::shared_ptr<Config>(new Config());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
typedef oatpp::base::String String;
|
||||
private:
|
||||
|
||||
static void writeString(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field);
|
||||
|
||||
template<class T>
|
||||
static void writeSimpleData(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field){
|
||||
auto value = oatpp::base::static_wrapper_cast<T>(field->get(object));
|
||||
stream->writeChar('\"');
|
||||
stream->write(field->name);
|
||||
stream->write("\": ", 3);
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
stream->writeAsString(value.get()->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
static void writeObject(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field);
|
||||
|
||||
static void writeListOfString(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list);
|
||||
|
||||
template<class T>
|
||||
static void writeListOfSimpleData(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list){
|
||||
stream->writeChar('[');
|
||||
bool first = true;
|
||||
auto curr = list->getFirstNode();
|
||||
while(curr != nullptr){
|
||||
|
||||
auto value = oatpp::base::static_wrapper_cast<T>(curr->getData());
|
||||
|
||||
if(first){
|
||||
first = false;
|
||||
} else {
|
||||
stream->write(", ", 2);
|
||||
}
|
||||
|
||||
if(value.isNull()){
|
||||
stream->write("null", 4);
|
||||
} else {
|
||||
stream->writeAsString(value.get()->getValue());
|
||||
}
|
||||
|
||||
curr = curr->getNext();
|
||||
}
|
||||
|
||||
stream->writeChar(']');
|
||||
|
||||
}
|
||||
|
||||
static void writeListOfObject(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list,
|
||||
const Type* const type);
|
||||
|
||||
static void writeListOfList(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list,
|
||||
const Type* const type);
|
||||
|
||||
static void writeListCollection(oatpp::data::stream::OutputStream* stream,
|
||||
AbstractList* list,
|
||||
const Type* const type);
|
||||
|
||||
static void writeList(oatpp::data::stream::OutputStream* stream,
|
||||
void* object,
|
||||
Property* field);
|
||||
|
||||
static void writeObject(oatpp::data::stream::OutputStream* stream,
|
||||
const Type* const type,
|
||||
Object* object);
|
||||
|
||||
public:
|
||||
|
||||
static void serialize(const std::shared_ptr<oatpp::data::stream::OutputStream>& stream,
|
||||
const oatpp::data::mapping::type::VariantWrapper& variant){
|
||||
auto type = variant.getValueType();
|
||||
if(type->name == oatpp::data::mapping::type::__class::AbstractObject::CLASS_NAME) {
|
||||
writeObject(stream.get(), type, static_cast<Object*>(variant.get()));
|
||||
} else if(type->name == oatpp::data::mapping::type::__class::AbstractList::CLASS_NAME) {
|
||||
writeListCollection(stream.get(), static_cast<AbstractList*>(variant.get()), type);
|
||||
} else {
|
||||
throw std::runtime_error("[oatpp::parser::json::mapping::Serializer::serialize()]: Unknown parameter type");
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif /* oatpp_parser_json_mapping_Serializer_hpp */
|
95
parser/test/json/mapping/DTOMapperPerfTest.cpp
Normal file
95
parser/test/json/mapping/DTOMapperPerfTest.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 "DTOMapperPerfTest.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/macro/basic.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/macro/codegen.hpp"
|
||||
|
||||
#include "../../../src/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/test/Checker.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
namespace {
|
||||
|
||||
typedef oatpp::parser::json::mapping::Serializer Serializer;
|
||||
typedef oatpp::parser::json::mapping::Deserializer Deserializer;
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class Test1 : public oatpp::data::mapping::type::Object {
|
||||
|
||||
DTO_INIT(Test1, Object)
|
||||
|
||||
DTO_FIELD(String, _string);
|
||||
DTO_FIELD(Int32, _int32);
|
||||
DTO_FIELD(List<Int32>::SharedWrapper, _list);
|
||||
|
||||
static SharedWrapper createTestInstance(){
|
||||
auto result = Test1::createShared();
|
||||
result->_string = "String Field";
|
||||
result->_int32 = 5;
|
||||
result->_list = List<Int32>::createShared();
|
||||
result->_list->pushBack(1);
|
||||
result->_list->pushBack(2);
|
||||
result->_list->pushBack(3);
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
bool DTOMapperPerfTest::onRun() {
|
||||
|
||||
v_int32 numIterations = 1000000;
|
||||
|
||||
auto mapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
|
||||
auto test1 = Test1::createTestInstance();
|
||||
auto test1_Text = mapper->writeToString(test1);
|
||||
OATPP_LOGV(TAG, "json='%s'", (const char*) test1_Text->getData());
|
||||
{
|
||||
PerformanceChecker checker("Serializer");
|
||||
for(v_int32 i = 0; i < numIterations; i ++) {
|
||||
mapper->writeToString(test1);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceChecker checker("Deserializer");
|
||||
auto caret = oatpp::parser::ParsingCaret::createShared(test1_Text);
|
||||
for(v_int32 i = 0; i < numIterations; i ++) {
|
||||
caret->setPosition(0);
|
||||
mapper->readFromCaret<Test1>(caret);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}}}
|
42
parser/test/json/mapping/DTOMapperPerfTest.hpp
Normal file
42
parser/test/json/mapping/DTOMapperPerfTest.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_DTOMapperPerfTest_hpp
|
||||
#define oatpp_test_parser_json_mapping_DTOMapperPerfTest_hpp
|
||||
|
||||
#include "../../../../../oatpp-lib/core/test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
class DTOMapperPerfTest : public UnitTest{
|
||||
public:
|
||||
|
||||
DTOMapperPerfTest():UnitTest("TEST[parser::json::mapping::DTOMapperPerfTest]"){}
|
||||
bool onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
|
||||
#endif /* oatpp_test_parser_json_mapping_DTOMapperPerfTest_hpp */
|
199
parser/test/json/mapping/DTOMapperTest.cpp
Normal file
199
parser/test/json/mapping/DTOMapperTest.cpp
Normal file
@ -0,0 +1,199 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "DTOMapperTest.hpp"
|
||||
|
||||
#include "../../../src/json/mapping/ObjectMapper.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Object.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/List.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/data/mapping/type/Primitive.hpp"
|
||||
|
||||
#include "../../../../../oatpp-lib/core/src/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
typedef oatpp::data::mapping::type::Object DTO;
|
||||
|
||||
class TestChild : public DTO {
|
||||
|
||||
DTO_INIT(TestChild, DTO)
|
||||
|
||||
static SharedWrapper createShared(const char* name, const char* secondName){
|
||||
auto result = createShared();
|
||||
result->name = name;
|
||||
result->secondName = secondName;
|
||||
return result;
|
||||
}
|
||||
|
||||
DTO_FIELD(String, name) = "Name";
|
||||
DTO_FIELD(String, secondName) = "Second Name";
|
||||
|
||||
};
|
||||
|
||||
class Test : public DTO {
|
||||
|
||||
DTO_INIT(Test, DTO)
|
||||
|
||||
DTO_FIELD(String, _string);
|
||||
DTO_FIELD(Int32, _int32);
|
||||
DTO_FIELD(Int64, _int64);
|
||||
DTO_FIELD(Float32, _float32);
|
||||
DTO_FIELD(Float64, _float64);
|
||||
DTO_FIELD(Boolean, _boolean);
|
||||
|
||||
DTO_FIELD(List<String>::SharedWrapper, _list_string) = List<String>::createShared();
|
||||
DTO_FIELD(List<Int32>::SharedWrapper, _list_int32) = List<Int32>::createShared();
|
||||
DTO_FIELD(List<Int64>::SharedWrapper, _list_int64) = List<Int64>::createShared();
|
||||
DTO_FIELD(List<Float32>::SharedWrapper, _list_float32) = List<Float32>::createShared();
|
||||
DTO_FIELD(List<Float64>::SharedWrapper, _list_float64) = List<Float64>::createShared();
|
||||
DTO_FIELD(List<Boolean>::SharedWrapper, _list_boolean) = List<Boolean>::createShared();
|
||||
|
||||
DTO_FIELD(List<TestChild::SharedWrapper>::SharedWrapper, _list_object) = List<TestChild::SharedWrapper>::createShared();
|
||||
DTO_FIELD(List<List<TestChild::SharedWrapper>::SharedWrapper>::SharedWrapper, _list_list_object) = List<List<TestChild::SharedWrapper>::SharedWrapper>::createShared();
|
||||
|
||||
DTO_FIELD(Test::SharedWrapper, obj1);
|
||||
DTO_FIELD(TestChild::SharedWrapper, child1);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
bool DTOMapperTest::onRun(){
|
||||
|
||||
auto mapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
|
||||
Test::SharedWrapper test1 = Test::createShared();
|
||||
|
||||
test1->_string = "string value";
|
||||
test1->_int32 = 32;
|
||||
test1->_int64 = 64;
|
||||
test1->_float32 = 0.32;
|
||||
test1->_float64 = 0.64;
|
||||
test1->_boolean = true;
|
||||
|
||||
test1->obj1 = Test::createShared();
|
||||
test1->obj1->_string = "inner string";
|
||||
test1->obj1->_list_string->pushBack("inner str_item_1");
|
||||
test1->obj1->_list_string->pushBack("inner str_item_2");
|
||||
test1->obj1->_list_string->pushBack("inner str_item_3");
|
||||
|
||||
test1->child1 = TestChild::createShared();
|
||||
test1->child1->name = "child1_name";
|
||||
test1->child1->secondName = "child1_second_name";
|
||||
|
||||
test1->_list_string->pushBack("str_item_1");
|
||||
test1->_list_string->pushBack("str_item_2");
|
||||
test1->_list_string->pushBack("str_item_3");
|
||||
|
||||
test1->_list_int32->pushBack(321);
|
||||
test1->_list_int32->pushBack(322);
|
||||
test1->_list_int32->pushBack(323);
|
||||
|
||||
test1->_list_int64->pushBack(641);
|
||||
test1->_list_int64->pushBack(642);
|
||||
test1->_list_int64->pushBack(643);
|
||||
|
||||
test1->_list_float32->pushBack(0.321);
|
||||
test1->_list_float32->pushBack(0.322);
|
||||
test1->_list_float32->pushBack(0.323);
|
||||
|
||||
test1->_list_float64->pushBack(0.641);
|
||||
test1->_list_float64->pushBack(0.642);
|
||||
test1->_list_float64->pushBack(0.643);
|
||||
|
||||
test1->_list_boolean->pushBack(true);
|
||||
test1->_list_boolean->pushBack(false);
|
||||
test1->_list_boolean->pushBack(true);
|
||||
|
||||
test1->_list_object->pushBack(TestChild::createShared("child", "1"));
|
||||
test1->_list_object->pushBack(TestChild::createShared("child", "2"));
|
||||
test1->_list_object->pushBack(TestChild::createShared("child", "3"));
|
||||
|
||||
auto l1 = DTO::List<TestChild::SharedWrapper>::createShared();
|
||||
auto l2 = DTO::List<TestChild::SharedWrapper>::createShared();
|
||||
auto l3 = DTO::List<TestChild::SharedWrapper>::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"));
|
||||
|
||||
l2->pushBack(TestChild::createShared("list_2", "item_1"));
|
||||
l2->pushBack(TestChild::createShared("list_2", "item_2"));
|
||||
l2->pushBack(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"));
|
||||
|
||||
test1->_list_list_object->pushBack(l1);
|
||||
test1->_list_list_object->pushBack(l2);
|
||||
test1->_list_list_object->pushBack(l3);
|
||||
|
||||
auto result = mapper->writeToString(test1);
|
||||
|
||||
OATPP_LOGD(TAG, "json='%s'", (const char*) result->getData());
|
||||
|
||||
OATPP_LOGD(TAG, "...");
|
||||
OATPP_LOGD(TAG, "...");
|
||||
OATPP_LOGD(TAG, "...");
|
||||
|
||||
auto config = oatpp::parser::json::mapping::Deserializer::Config::createShared();
|
||||
auto caret = oatpp::parser::ParsingCaret::createShared(result);
|
||||
auto obj = mapper->readFromCaret<Test>(caret);
|
||||
|
||||
OATPP_ASSERT(obj->_string.isNull() == false);
|
||||
OATPP_ASSERT(obj->_string->equals(test1->_string));
|
||||
|
||||
OATPP_ASSERT(obj->_int32.isNull() == false);
|
||||
OATPP_ASSERT(obj->_int32->getValue() == test1->_int32->getValue());
|
||||
|
||||
OATPP_ASSERT(obj->_int64.isNull() == false);
|
||||
OATPP_ASSERT(obj->_int64->getValue() == test1->_int64->getValue());
|
||||
|
||||
OATPP_ASSERT(obj->_float32.isNull() == false);
|
||||
OATPP_ASSERT(obj->_float32->getValue() == test1->_float32->getValue());
|
||||
|
||||
OATPP_ASSERT(obj->_float64.isNull() == false);
|
||||
OATPP_ASSERT(obj->_float64->getValue() == test1->_float64->getValue());
|
||||
|
||||
OATPP_ASSERT(obj->_boolean.isNull() == false);
|
||||
OATPP_ASSERT(obj->_boolean->getValue() == test1->_boolean->getValue());
|
||||
|
||||
result = mapper->writeToString(obj);
|
||||
|
||||
OATPP_LOGD(TAG, "json='%s'", (const char*) result->getData());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}}}}}
|
42
parser/test/json/mapping/DTOMapperTest.hpp
Normal file
42
parser/test/json/mapping/DTOMapperTest.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_DTOMapperTest_hpp
|
||||
#define oatpp_test_parser_json_mapping_DTOMapperTest_hpp
|
||||
|
||||
#include "../../../../../oatpp-lib/core/test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
class DTOMapperTest : public UnitTest{
|
||||
public:
|
||||
|
||||
DTOMapperTest():UnitTest("TEST[parser::json::mapping::DTOMapperTest]"){}
|
||||
bool onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
|
||||
#endif /* oatpp_test_parser_json_mapping_DTOMapperTest_hpp */
|
150
parser/test/json/mapping/DeserializerTest.cpp
Normal file
150
parser/test/json/mapping/DeserializerTest.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* 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 "DeserializerTest.hpp"
|
||||
|
||||
#include "../../../src/json/mapping/ObjectMapper.hpp"
|
||||
#include "../../../../../oatpp-lib/core/src/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace parser { namespace json { namespace mapping {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
typedef oatpp::data::mapping::type::Object DTO;
|
||||
typedef oatpp::parser::ParsingCaret ParsingCaret;
|
||||
typedef oatpp::parser::json::mapping::Serializer Serializer;
|
||||
typedef oatpp::parser::json::mapping::Deserializer Deserializer;
|
||||
|
||||
class Test1 : public DTO {
|
||||
|
||||
DTO_INIT(Test1, DTO)
|
||||
|
||||
DTO_FIELD(String, strF);
|
||||
|
||||
};
|
||||
|
||||
class Test2 : public DTO {
|
||||
|
||||
DTO_INIT(Test2, DTO)
|
||||
|
||||
DTO_FIELD(Int32, int32F);
|
||||
|
||||
};
|
||||
|
||||
class Test3 : public DTO {
|
||||
|
||||
DTO_INIT(Test3, DTO)
|
||||
|
||||
DTO_FIELD(Float32, float32F);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
bool DeserializerTest::onRun(){
|
||||
|
||||
auto mapper = oatpp::parser::json::mapping::ObjectMapper::createShared();
|
||||
|
||||
auto obj1 = mapper->readFromString<Test1>("{}");
|
||||
|
||||
OATPP_ASSERT(obj1.isNull() == false);
|
||||
OATPP_ASSERT(obj1->strF.isNull());
|
||||
|
||||
obj1 = mapper->readFromString<Test1>("{\"strF\":\"value1\"}");
|
||||
|
||||
OATPP_ASSERT(obj1.isNull() == false);
|
||||
OATPP_ASSERT(obj1->strF.isNull() == false);
|
||||
OATPP_ASSERT(obj1->strF->equals("value1"));
|
||||
|
||||
obj1 = mapper->readFromString<Test1>("{\n\r\t\f\"strF\"\n\r\t\f:\n\r\t\f\"value1\"\n\r\t\f}");
|
||||
|
||||
OATPP_ASSERT(obj1.isNull() == false);
|
||||
OATPP_ASSERT(obj1->strF.isNull() == false);
|
||||
OATPP_ASSERT(obj1->strF->equals("value1"));
|
||||
|
||||
auto obj2 = mapper->readFromString<Test2>("{\"int32F\": null}");
|
||||
|
||||
OATPP_ASSERT(obj2.isNull() == false);
|
||||
OATPP_ASSERT(obj2->int32F.isNull() == true);
|
||||
|
||||
obj2 = mapper->readFromString<Test2>("{\"int32F\": 32}");
|
||||
|
||||
OATPP_ASSERT(obj2.isNull() == false);
|
||||
OATPP_ASSERT(obj2->int32F->getValue() == 32);
|
||||
|
||||
obj2 = mapper->readFromString<Test2>("{\"int32F\": -32}");
|
||||
|
||||
OATPP_ASSERT(obj2.isNull() == false);
|
||||
OATPP_ASSERT(obj2->int32F->getValue() == -32);
|
||||
|
||||
auto obj3 = mapper->readFromString<Test3>("{\"float32F\": null}");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F.isNull() == true);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": 32}");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F->getValue() == 32);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": 1.32e1}");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F.isNull() == false);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": 1.32e+1 }");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F.isNull() == false);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": 1.32e-1 }");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F.isNull() == false);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": -1.32E-1 }");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F.isNull() == false);
|
||||
|
||||
obj3 = mapper->readFromString<Test3>("{\"float32F\": -1.32E1 }");
|
||||
|
||||
OATPP_ASSERT(obj3.isNull() == false);
|
||||
OATPP_ASSERT(obj3->float32F.isNull() == false);
|
||||
|
||||
auto list = mapper->readFromString<Test1::List<Test1::Int32>>("[1, 2, 3]");
|
||||
OATPP_ASSERT(list.isNull() == false);
|
||||
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);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}}}}}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user