Initial commit. Separated from lganzzzo's private repo.

This commit is contained in:
lganzzzo 2018-03-13 04:36:20 +02:00
parent 8914b7d695
commit 28e6032dd9
151 changed files with 15830 additions and 0 deletions

View 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
}
}}

View 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 */

View 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;
}
}}

View 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 */

View 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"

View 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
View 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
View 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 */

View 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"

View 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 */

View 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();
}
}}}

View 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 */

View 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"

View 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 */

View 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"

View 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 */

View 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"

View 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 */

View 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);
}
}}

View 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 */

View 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"

View 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 */

View 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);
}
}}

View 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 */

View 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"

View 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 */

View 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;
}}}

View 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 */

View 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"

View 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 */

View 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"

View 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 */

View 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"

View 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 &map;
}
};
}}}}
#endif /* oatpp_data_type_Object_hpp */

View 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);
}
}
}}}}

View 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 */

View 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;
}
}
}}}}

View 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 */

View 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 &map; \
} \
\
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__))
///

View 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

View 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;
}
}}}

View 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 */

View 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"

View 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 */

View 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;
}
}
}}}

View 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) */

View 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;
}
}
}
}}}

View File

@ -0,0 +1,177 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#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
View 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 */

View 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 */

View 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 */

View 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);
}
}}}

View 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 */

View 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;
}
}}

View 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 */

View 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;
}
}}}

View 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
View 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
View 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
View 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
View 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__) */

View 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;
}
}}}

View 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 */

View 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;
}
}}}

View 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 */

View 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;
}
}}}

View 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 */

View 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;
}
}}}

View 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
View 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
View 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
View 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
View 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 */

View 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;
}
}}}

View 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 */

View 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);
}
}}

View 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 */

View 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 {
}}

View 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 */

View 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);
}
}}}

View 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 */

View 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"

View File

@ -0,0 +1,40 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#ifndef 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 */

View 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();
}
}}}

View 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 */

View 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);
}
}}}

View 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
View 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
View 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 */

View 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();
}
}}}}

View 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 */

View 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"

View 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 */

View 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('}');
}
}}}}

View 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 */

View File

@ -0,0 +1,95 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************/
#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;
}
}}}}}

View 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 */

View 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)
}}}}}

View 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 */

View 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