mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2024-12-22 22:16:37 +08:00
Remove memory pools. Remove ChunkedBuffer.
This commit is contained in:
parent
97d7597112
commit
5d2f8693eb
@ -58,12 +58,6 @@ add_library(oatpp
|
||||
oatpp/core/base/Environment.cpp
|
||||
oatpp/core/base/Environment.hpp
|
||||
oatpp/core/base/ObjectHandle.hpp
|
||||
oatpp/core/base/memory/Allocator.cpp
|
||||
oatpp/core/base/memory/Allocator.hpp
|
||||
oatpp/core/base/memory/MemoryPool.cpp
|
||||
oatpp/core/base/memory/MemoryPool.hpp
|
||||
oatpp/core/base/memory/ObjectPool.cpp
|
||||
oatpp/core/base/memory/ObjectPool.hpp
|
||||
oatpp/core/concurrency/SpinLock.cpp
|
||||
oatpp/core/concurrency/SpinLock.hpp
|
||||
oatpp/core/concurrency/Thread.cpp
|
||||
@ -116,8 +110,6 @@ add_library(oatpp
|
||||
oatpp/core/data/share/StringTemplate.hpp
|
||||
oatpp/core/data/stream/BufferStream.cpp
|
||||
oatpp/core/data/stream/BufferStream.hpp
|
||||
oatpp/core/data/stream/ChunkedBuffer.cpp
|
||||
oatpp/core/data/stream/ChunkedBuffer.hpp
|
||||
oatpp/core/data/stream/FIFOStream.cpp
|
||||
oatpp/core/data/stream/FIFOStream.hpp
|
||||
oatpp/core/data/stream/FileStream.cpp
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include "UnitTest.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/MemoryPool.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace oatpp { namespace test {
|
||||
@ -58,16 +56,6 @@ void UnitTest::run(v_int32 times) {
|
||||
}else{
|
||||
|
||||
OATPP_LOGE(TAG, "\033[1mFINISHED\033[0m - \033[1;31mfailed\033[0m, leakingObjects = %d", leakingObjects);
|
||||
|
||||
auto POOLS = oatpp::base::memory::MemoryPool::POOLS;
|
||||
auto it = POOLS.begin();
|
||||
while (it != POOLS.end()) {
|
||||
auto pool = it->second;
|
||||
if(pool->getObjectsCount() != 0) {
|
||||
OATPP_LOGV("Pool", "name: '%s' [%d(objs)]", pool->getName().c_str(), pool->getObjectsCount());
|
||||
}
|
||||
it ++;
|
||||
}
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "oatpp/core/async/utils/FastQueue.hpp"
|
||||
|
||||
#include "oatpp/core/IODefinitions.hpp"
|
||||
#include "oatpp/core/base/memory/MemoryPool.hpp"
|
||||
#include "oatpp/core/base/Environment.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
@ -1,34 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "Allocator.hpp"
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
AllocatorPoolInfo::AllocatorPoolInfo(const char* pPoolName, v_buff_size pPoolChunkSize)
|
||||
: poolName(pPoolName)
|
||||
, poolChunkSize(pPoolChunkSize)
|
||||
{}
|
||||
|
||||
}}}
|
@ -1,275 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_base_memory_Allocator_hpp
|
||||
#define oatpp_base_memory_Allocator_hpp
|
||||
|
||||
#include "./MemoryPool.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
/**
|
||||
* Pool Information for Pool Allocators.
|
||||
*/
|
||||
class AllocatorPoolInfo {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param pPoolName - memory pool name.
|
||||
* @param pPoolChunkSize - memory pool chunk size. For more about chunk size see &id:oatpp::base::memory::MemoryPool::MemoryPool;.
|
||||
*/
|
||||
AllocatorPoolInfo(const char* pPoolName, v_buff_size pPoolChunkSize);
|
||||
|
||||
/**
|
||||
* Memory pool name.
|
||||
*/
|
||||
const char* const poolName;
|
||||
|
||||
/**
|
||||
* Memory pool chunk size.
|
||||
* For more about chunk size see &id:oatpp::base::memory::MemoryPool::MemoryPool;.
|
||||
*/
|
||||
const v_buff_size poolChunkSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocator to allocate shared object on &id:oatpp::base::memory::MemoryPool;
|
||||
* Used to allocate shared_ptr control block and an object in the same memory entry of the pool.
|
||||
* @tparam T - type of the object to allocate.
|
||||
*/
|
||||
template<class T>
|
||||
class PoolSharedObjectAllocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
public:
|
||||
const AllocatorPoolInfo& m_poolInfo;
|
||||
public:
|
||||
static ThreadDistributedMemoryPool& getPool(const AllocatorPoolInfo& info){
|
||||
static auto pool = new ThreadDistributedMemoryPool(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) {
|
||||
(void)n;
|
||||
return static_cast<T*>(getPool(m_poolInfo).obtain());
|
||||
}
|
||||
|
||||
void deallocate(T* ptr, size_t n) {
|
||||
(void)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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as &l:PoolSharedObjectAllocator; but uses `thread_local` &id:oatpp::base::memory::MemoryPool;. <br>
|
||||
* *If built with OATPP_COMPAT_BUILD_NO_THREAD_LOCAL flag - same as &l:PoolSharedObjectAllocator;.*
|
||||
* @tparam T - type of the object to allocate.
|
||||
*/
|
||||
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){
|
||||
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
|
||||
static thread_local oatpp::base::memory::MemoryPool pool(info.poolName, sizeof(T), info.poolChunkSize);
|
||||
return pool;
|
||||
#else
|
||||
static auto pool = new MemoryPool(info.poolName, sizeof(T), info.poolChunkSize);
|
||||
return *pool;
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
ThreadLocalPoolSharedObjectAllocator(const AllocatorPoolInfo& info)
|
||||
: m_poolInfo(info)
|
||||
{};
|
||||
|
||||
template<typename U>
|
||||
ThreadLocalPoolSharedObjectAllocator(const ThreadLocalPoolSharedObjectAllocator<U>& other)
|
||||
: m_poolInfo(other.m_poolInfo)
|
||||
{}
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
(void)n;
|
||||
return static_cast<T*>(getPool(m_poolInfo).obtain());
|
||||
}
|
||||
|
||||
void deallocate(T* ptr, size_t n) {
|
||||
(void)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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra information for, and about allocation.
|
||||
* Used for variable-size objects allocations. (ex.: for strings).
|
||||
*/
|
||||
class AllocationExtras {
|
||||
public:
|
||||
AllocationExtras(v_buff_size pExtraWanted)
|
||||
: extraWanted(pExtraWanted)
|
||||
{}
|
||||
const v_buff_size extraWanted;
|
||||
void* extraPtr;
|
||||
v_buff_size baseSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocator for shared objects.
|
||||
* Used to allocate object and shared_ptr's control block in the same memory entry.
|
||||
* @tparam T - type of the object to allocate.
|
||||
*/
|
||||
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)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) {
|
||||
(void)n;
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocator for shared objects. Allocates objects on the pool provided.
|
||||
* @tparam T - type of object to allocate.
|
||||
* @tparam P - type of memory pool to allocate object on.
|
||||
*/
|
||||
template<class T, class P>
|
||||
class CustomPoolSharedObjectAllocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
public:
|
||||
AllocationExtras& m_info;
|
||||
P& m_pool;
|
||||
public:
|
||||
|
||||
CustomPoolSharedObjectAllocator(AllocationExtras& info, P& pool)
|
||||
: m_info(info)
|
||||
, m_pool(pool)
|
||||
{};
|
||||
|
||||
template<typename U>
|
||||
CustomPoolSharedObjectAllocator(const CustomPoolSharedObjectAllocator<U, P>& other)
|
||||
: m_info(other.m_info)
|
||||
, m_pool(other.m_pool)
|
||||
{}
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
(void)n;
|
||||
void* mem = m_pool.obtain();
|
||||
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) {
|
||||
(void)n;
|
||||
oatpp::base::memory::MemoryPool::free(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){
|
||||
typedef SharedObjectAllocator<T> _Allocator;
|
||||
_Allocator allocator(extras);
|
||||
return std::allocate_shared<T, _Allocator>(allocator, args...);
|
||||
}
|
||||
|
||||
template<typename T, typename P, typename ... Args>
|
||||
static std::shared_ptr<T> customPoolAllocateSharedWithExtras(AllocationExtras& extras, P& pool, Args... args){
|
||||
typedef CustomPoolSharedObjectAllocator<T, P> _Allocator;
|
||||
_Allocator allocator(extras, pool);
|
||||
return std::allocate_shared<T, _Allocator>(allocator, args...);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_base_memory_Allocator_hpp */
|
@ -1,187 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "MemoryPool.hpp"
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
#include "oatpp/core/concurrency/Thread.hpp"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
MemoryPool::MemoryPool(const std::string& name, v_buff_size entrySize, v_buff_size chunkSize)
|
||||
: m_name(name)
|
||||
, m_entrySize(entrySize)
|
||||
, m_chunkSize(chunkSize)
|
||||
, m_id(++poolIdCounter)
|
||||
, m_rootEntry(nullptr)
|
||||
, m_objectsCount(0)
|
||||
{
|
||||
allocChunk();
|
||||
std::lock_guard<oatpp::concurrency::SpinLock> lock(POOLS_SPIN_LOCK);
|
||||
POOLS[m_id] = this;
|
||||
}
|
||||
|
||||
MemoryPool::~MemoryPool() {
|
||||
auto it = m_chunks.begin();
|
||||
while (it != m_chunks.end()) {
|
||||
p_char8 chunk = *it;
|
||||
delete [] chunk;
|
||||
it++;
|
||||
}
|
||||
std::lock_guard<oatpp::concurrency::SpinLock> lock(POOLS_SPIN_LOCK);
|
||||
POOLS.erase(m_id);
|
||||
}
|
||||
|
||||
void MemoryPool::allocChunk() {
|
||||
#ifdef OATPP_DISABLE_POOL_ALLOCATIONS
|
||||
// DO NOTHING
|
||||
#else
|
||||
v_buff_size entryBlockSize = sizeof(EntryHeader) + m_entrySize;
|
||||
v_buff_size chunkMemSize = entryBlockSize * m_chunkSize;
|
||||
p_char8 mem = new v_char8[chunkMemSize];
|
||||
m_chunks.push_back(mem);
|
||||
for(v_buff_size i = 0; i < m_chunkSize; i++){
|
||||
EntryHeader* entry = new (mem + i * entryBlockSize) EntryHeader(this, m_id, m_rootEntry);
|
||||
m_rootEntry = entry;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void* MemoryPool::obtain() {
|
||||
#ifdef OATPP_DISABLE_POOL_ALLOCATIONS
|
||||
return new v_char8[m_entrySize];
|
||||
#else
|
||||
std::lock_guard<oatpp::concurrency::SpinLock> lock(m_lock);
|
||||
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:obtain()]: Unable to allocate entry");
|
||||
}
|
||||
auto entry = m_rootEntry;
|
||||
m_rootEntry = m_rootEntry->next;
|
||||
++ m_objectsCount;
|
||||
return ((p_char8) entry) + sizeof(EntryHeader);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MemoryPool::freeByEntryHeader(EntryHeader* entry) {
|
||||
if(entry->poolId == m_id) {
|
||||
std::lock_guard<oatpp::concurrency::SpinLock> lock(m_lock);
|
||||
entry->next = m_rootEntry;
|
||||
m_rootEntry = entry;
|
||||
-- m_objectsCount;
|
||||
} else {
|
||||
OATPP_LOGD("[oatpp::base::memory::MemoryPool::freeByEntryHeader()]",
|
||||
"Error. Invalid EntryHeader. Expected poolId=%d, entry poolId=%d", m_id, entry->poolId);
|
||||
throw std::runtime_error("[oatpp::base::memory::MemoryPool::freeByEntryHeader()]: Invalid EntryHeader");
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryPool::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 MemoryPool::getName(){
|
||||
return m_name;
|
||||
}
|
||||
|
||||
v_buff_size MemoryPool::getEntrySize(){
|
||||
return m_entrySize;
|
||||
}
|
||||
|
||||
v_buff_size MemoryPool::getSize(){
|
||||
return m_chunks.size() * m_chunkSize;
|
||||
}
|
||||
|
||||
v_int64 MemoryPool::getObjectsCount(){
|
||||
return m_objectsCount;
|
||||
}
|
||||
|
||||
oatpp::concurrency::SpinLock MemoryPool::POOLS_SPIN_LOCK;
|
||||
std::unordered_map<v_int64, MemoryPool*> MemoryPool::POOLS;
|
||||
std::atomic<v_int64> MemoryPool::poolIdCounter(0);
|
||||
|
||||
const v_int64 ThreadDistributedMemoryPool::SHARDS_COUNT_DEFAULT = OATPP_THREAD_DISTRIBUTED_MEM_POOL_SHARDS_COUNT;
|
||||
|
||||
#if defined(OATPP_DISABLE_POOL_ALLOCATIONS) || defined(OATPP_COMPAT_BUILD_NO_THREAD_LOCAL)
|
||||
ThreadDistributedMemoryPool::ThreadDistributedMemoryPool(const std::string& name, v_buff_size entrySize, v_buff_size chunkSize, v_int64 shardsCount)
|
||||
: m_shardsCount(1)
|
||||
, m_shards(new MemoryPool*[1])
|
||||
, m_deleted(false)
|
||||
{
|
||||
for(v_int64 i = 0; i < m_shardsCount; i++){
|
||||
m_shards[i] = new MemoryPool(name + "_" + oatpp::utils::conversion::int64ToStdStr(i), entrySize, chunkSize);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ThreadDistributedMemoryPool::ThreadDistributedMemoryPool(const std::string& name, v_buff_size entrySize, v_buff_size chunkSize, v_int64 shardsCount)
|
||||
: m_shardsCount(shardsCount)
|
||||
, m_shards(new MemoryPool*[m_shardsCount])
|
||||
, m_deleted(false)
|
||||
{
|
||||
for(v_int64 i = 0; i < m_shardsCount; i++){
|
||||
m_shards[i] = new MemoryPool(name + "_" + oatpp::utils::conversion::int64ToStdStr(i), entrySize, chunkSize);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ThreadDistributedMemoryPool::~ThreadDistributedMemoryPool(){
|
||||
m_deleted = true;
|
||||
for(v_int64 i = 0; i < m_shardsCount; i++){
|
||||
delete m_shards[i];
|
||||
}
|
||||
delete [] m_shards;
|
||||
}
|
||||
|
||||
#if defined(OATPP_DISABLE_POOL_ALLOCATIONS) || defined(OATPP_COMPAT_BUILD_NO_THREAD_LOCAL)
|
||||
void* ThreadDistributedMemoryPool::obtain() {
|
||||
if(m_deleted) {
|
||||
throw std::runtime_error("[oatpp::base::memory::ThreadDistributedMemoryPool::obtain()]. Error. Pool deleted.");
|
||||
}
|
||||
return m_shards[0]->obtain();
|
||||
}
|
||||
#else
|
||||
void* ThreadDistributedMemoryPool::obtain() {
|
||||
if(m_deleted) {
|
||||
throw std::runtime_error("[oatpp::base::memory::ThreadDistributedMemoryPool::obtain()]. Error. Pool deleted.");
|
||||
}
|
||||
static std::atomic<v_uint16> base(0);
|
||||
static thread_local v_int16 index = (++base) % m_shardsCount;
|
||||
return m_shards[index]->obtain();
|
||||
}
|
||||
#endif
|
||||
|
||||
}}}
|
@ -1,278 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_base_memory_MemoryPool_hpp
|
||||
#define oatpp_base_memory_MemoryPool_hpp
|
||||
|
||||
#include "oatpp/core/concurrency/SpinLock.hpp"
|
||||
#include "oatpp/core/base/Environment.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <cstring>
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
/**
|
||||
* Memory Pool allocates memory chunks. Each chunk consists of specified number of fixed-size entries.
|
||||
* Entries can be obtained and freed by user. When memory pool runs out of free entries, new chunk is allocated.
|
||||
*/
|
||||
class MemoryPool {
|
||||
public:
|
||||
static oatpp::concurrency::SpinLock POOLS_SPIN_LOCK;
|
||||
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();
|
||||
void freeByEntryHeader(EntryHeader* entry);
|
||||
private:
|
||||
std::string m_name;
|
||||
v_buff_size m_entrySize;
|
||||
v_buff_size m_chunkSize;
|
||||
v_int64 m_id;
|
||||
std::list<p_char8> m_chunks;
|
||||
EntryHeader* m_rootEntry;
|
||||
v_int64 m_objectsCount;
|
||||
oatpp::concurrency::SpinLock m_lock;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param name - name of the pool.
|
||||
* @param entrySize - size of the entry in bytes returned in call to &l:MemoryPool::obtain ();.
|
||||
* @param chunkSize - number of entries in one chunk.
|
||||
*/
|
||||
MemoryPool(const std::string& name, v_buff_size entrySize, v_buff_size chunkSize);
|
||||
|
||||
/**
|
||||
* Deleted copy-constructor.
|
||||
*/
|
||||
MemoryPool(const MemoryPool&) = delete;
|
||||
|
||||
/**
|
||||
* Virtual destructor.
|
||||
*/
|
||||
virtual ~MemoryPool();
|
||||
|
||||
/**
|
||||
* Obtain pointer to memory entry.
|
||||
* When entry is no more needed, user must call &id:oatpp::base::memory::MemoryPool::free; and pass obtained entry pointer as a parameter.
|
||||
* @return - pointer to memory entry.
|
||||
*/
|
||||
void* obtain();
|
||||
|
||||
/**
|
||||
* Free obtained earlier memory entry.
|
||||
* This method is static, because entry "knows" to what pool it belongs.
|
||||
* @param entry - entry obtained by call to &l:MemoryPool::obtain ();
|
||||
*/
|
||||
static void free(void* entry);
|
||||
|
||||
/**
|
||||
* Get name of the memory pool.
|
||||
* @return - memory pool name as `std::string`.
|
||||
*/
|
||||
std::string getName();
|
||||
|
||||
/**
|
||||
* Get size of the memory entry in bytes which can be obtained by call to &l:MemoryPool::obtain ();.
|
||||
* @return - size of the enrty in bytes.
|
||||
*/
|
||||
v_buff_size getEntrySize();
|
||||
|
||||
/**
|
||||
* Get size of the memory allocated by memory pool.
|
||||
* @return - size of the memory allocated by memory pool.
|
||||
*/
|
||||
v_buff_size getSize();
|
||||
|
||||
/**
|
||||
* Get number of entries currently in use.
|
||||
* @return - number of entries currently in use.
|
||||
*/
|
||||
v_int64 getObjectsCount();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates multiple MemoryPools (&l:MemoryPool;) to reduce concurrency blocking in call to &l:ThreadDistributedMemoryPool::obtain ();
|
||||
*/
|
||||
class ThreadDistributedMemoryPool {
|
||||
private:
|
||||
v_int64 m_shardsCount;
|
||||
MemoryPool** m_shards;
|
||||
bool m_deleted;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default number of MemoryPools (&l:MemoryPool;) "shards" to create.
|
||||
*/
|
||||
static const v_int64 SHARDS_COUNT_DEFAULT;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param name - name of the memory pool.
|
||||
* @param entrySize - size of memory pool entry.
|
||||
* @param chunkSize - number of entries in chunk.
|
||||
* @param shardsCount - number of MemoryPools (&l:MemoryPool;) "shards" to create.
|
||||
*/
|
||||
ThreadDistributedMemoryPool(const std::string& name, v_buff_size entrySize, v_buff_size chunkSize,
|
||||
v_int64 shardsCount = SHARDS_COUNT_DEFAULT);
|
||||
|
||||
/**
|
||||
* Deleted copy-constructor.
|
||||
*/
|
||||
ThreadDistributedMemoryPool(const ThreadDistributedMemoryPool&) = delete;
|
||||
|
||||
virtual ~ThreadDistributedMemoryPool();
|
||||
|
||||
/**
|
||||
* Obtain pointer to memory entry.
|
||||
* When entry is no more needed, user must call &id:oatpp::base::memory::MemoryPool::free; and pass obtained entry pointer as a parameter.
|
||||
* @return - pointer to memory entry.
|
||||
*/
|
||||
void* obtain();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Not thread-safe pool of objects of specified type.
|
||||
* @tparam T - object type.
|
||||
*/
|
||||
template<typename T>
|
||||
class Bench {
|
||||
private:
|
||||
|
||||
class Block {
|
||||
public:
|
||||
Block(p_char8 mem, Block* pNext)
|
||||
: memory(mem)
|
||||
, next(pNext)
|
||||
{}
|
||||
p_char8 memory;
|
||||
Block* next;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void grow(){
|
||||
|
||||
v_buff_size newSize = m_size + m_growSize;
|
||||
T** newIndex = new T*[newSize];
|
||||
std::memcpy(newIndex, m_index, m_size);
|
||||
|
||||
Block* b = new Block(new v_char8 [m_growSize * sizeof(T)], m_blocks);
|
||||
m_blocks = b;
|
||||
for(v_buff_size i = 0; i < m_growSize; i++) {
|
||||
newIndex[m_size + i] = (T*) (&b->memory[i * sizeof(T)]);
|
||||
}
|
||||
|
||||
delete [] m_index;
|
||||
m_size = newSize;
|
||||
m_index = newIndex;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
v_buff_size m_growSize;
|
||||
v_buff_size m_size;
|
||||
v_buff_size m_indexPosition;
|
||||
Block* m_blocks;
|
||||
T** m_index;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param growSize - number of objects to allocate when no free objects left.
|
||||
*/
|
||||
Bench(v_buff_size growSize)
|
||||
: m_growSize(growSize)
|
||||
, m_size(0)
|
||||
, m_indexPosition(0)
|
||||
, m_blocks(nullptr)
|
||||
, m_index(nullptr)
|
||||
{
|
||||
grow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Non virtual destructor.
|
||||
*/
|
||||
~Bench(){
|
||||
auto curr = m_blocks;
|
||||
while (curr != nullptr) {
|
||||
auto next = curr->next;
|
||||
delete curr;
|
||||
curr = next;
|
||||
}
|
||||
delete [] m_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct object and get pointer to constructed object.
|
||||
* @tparam Args - arguments to be passed to object constructor.
|
||||
* @param args - actual arguments to pass to object constructor.
|
||||
* @return - pointer to constructed object.
|
||||
*/
|
||||
template<typename ... Args>
|
||||
T* obtain(Args... args) {
|
||||
if(m_indexPosition == m_size) {
|
||||
grow();
|
||||
}
|
||||
return new (m_index[m_indexPosition ++]) T(args...);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call object destructor and put it on "bench".
|
||||
* @param entry - object to be freed.
|
||||
*/
|
||||
void free(T* entry) {
|
||||
entry->~T();
|
||||
m_index[--m_indexPosition] = entry;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_base_memory_MemoryPool_hpp */
|
@ -1,25 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "ObjectPool.hpp"
|
@ -1,201 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_base_memory_ObjectPool_hpp
|
||||
#define oatpp_base_memory_ObjectPool_hpp
|
||||
|
||||
#include "./Allocator.hpp"
|
||||
#include "./MemoryPool.hpp"
|
||||
|
||||
namespace oatpp { namespace base { namespace memory {
|
||||
|
||||
/**
|
||||
* Macro to declare object pool class which uses &id:oatpp::base::memory::PoolSharedObjectAllocator; to allocate objects.
|
||||
* @param NAME - name of the memory pool.
|
||||
* @param TYPE - type of the object.
|
||||
* @param CHUNK_SIZE - chunk size for &id:oatpp::base::memory::MemoryPool;.
|
||||
*/
|
||||
#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::allocate_shared<TYPE, Allocator>(getAllocator(), args...); \
|
||||
} \
|
||||
\
|
||||
};
|
||||
|
||||
/**
|
||||
* Macro to declare object pool class which uses &id:oatpp::base::memory::ThreadLocalPoolSharedObjectAllocator; to allocate objects.
|
||||
* @param NAME - name of the memory pool.
|
||||
* @param TYPE - type of the object.
|
||||
* @param CHUNK_SIZE - chunk size for &id:oatpp::base::memory::MemoryPool;.
|
||||
*/
|
||||
#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::allocate_shared<TYPE, Allocator>(getAllocator(), args...); \
|
||||
} \
|
||||
\
|
||||
};
|
||||
|
||||
/**
|
||||
* Macro to declare: &id:oatpp::base::memory::MemoryPool; for object, plus class-specific operators
|
||||
* `static void* operator new(std::size_t sz)`, `static void operator delete(void* ptr, std::size_t sz)`,
|
||||
* `static void* operator new(std::size_t sz, void* entry)`, `static void operator delete(void* ptr, void* entry)`.
|
||||
* @param NAME - name of the memory pool.
|
||||
* @param TYPE - type of the object.
|
||||
* @param CHUNK_SIZE - chunk size for &id:oatpp::base::memory::MemoryPool;.
|
||||
*/
|
||||
#define OBJECT_POOL(POOL_NAME, TYPE, CHUNK_SIZE) \
|
||||
class POOL_NAME { \
|
||||
public: \
|
||||
\
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getPool(){ \
|
||||
static auto pool = new oatpp::base::memory::ThreadDistributedMemoryPool(#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)){ \
|
||||
oatpp::base::Environment::log(2, #POOL_NAME, "[ERROR|CRITICAL]: MemoryPool malfunction. Deleting object of wrong 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) { \
|
||||
(void)ptr; \
|
||||
(void)entry; \
|
||||
}
|
||||
|
||||
#ifndef OATPP_COMPAT_BUILD_NO_THREAD_LOCAL
|
||||
/**
|
||||
* Macro to declare: `thread_local` &id:oatpp::base::memory::MemoryPool; for object, plus class-specific operators <br>
|
||||
* `static void* operator new(std::size_t sz)`, `static void operator delete(void* ptr, std::size_t sz)`, <br>
|
||||
* `static void* operator new(std::size_t sz, void* entry)`, `static void operator delete(void* ptr, void* entry)`. <br>
|
||||
* *Memory pool is NOT `thread_local` if built with `-DOATPP_COMPAT_BUILD_NO_THREAD_LOCAL` flag*
|
||||
* @param NAME - name of the memory pool.
|
||||
* @param TYPE - type of the object.
|
||||
* @param CHUNK_SIZE - chunk size for &id:oatpp::base::memory::MemoryPool;.
|
||||
*/
|
||||
#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)){ \
|
||||
oatpp::base::Environment::log(2, #POOL_NAME, "[ERROR|CRITICAL]: MemoryPool malfunction. Deleting object of wrong 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) { \
|
||||
(void)ptr; \
|
||||
(void)entry; \
|
||||
}
|
||||
#else
|
||||
#define OBJECT_POOL_THREAD_LOCAL(POOL_NAME, TYPE, CHUNK_SIZE) \
|
||||
class POOL_NAME { \
|
||||
public: \
|
||||
\
|
||||
static oatpp::base::memory::MemoryPool& getPool(){ \
|
||||
static auto pool = new oatpp::base::memory::MemoryPool(#POOL_NAME"<"#TYPE">", sizeof(TYPE), CHUNK_SIZE); \
|
||||
return *pool; \
|
||||
} \
|
||||
\
|
||||
};
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_base_memory_ObjectPool_hpp */
|
@ -29,15 +29,15 @@ namespace oatpp { namespace data { namespace buffer {
|
||||
const v_buff_size IOBuffer::BUFFER_SIZE = 4096;
|
||||
|
||||
IOBuffer::IOBuffer()
|
||||
: m_entry(getBufferPool().obtain())
|
||||
: m_entry(new v_char8[BUFFER_SIZE])
|
||||
{}
|
||||
|
||||
std::shared_ptr<IOBuffer> IOBuffer::createShared(){
|
||||
return Shared_IOBuffer_Pool::allocateShared();
|
||||
return std::make_shared<IOBuffer>();
|
||||
}
|
||||
|
||||
IOBuffer::~IOBuffer() {
|
||||
oatpp::base::memory::MemoryPool::free(m_entry);
|
||||
delete [] m_entry;
|
||||
}
|
||||
|
||||
void* IOBuffer::getData(){
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef oatpp_data_buffer_IOBuffer_hpp
|
||||
#define oatpp_data_buffer_IOBuffer_hpp
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace buffer {
|
||||
@ -35,21 +34,13 @@ namespace oatpp { namespace data{ namespace buffer {
|
||||
* Allocates buffer bytes using &id:oatpp::base::memory::ThreadDistributedMemoryPool;.
|
||||
*/
|
||||
class IOBuffer : public oatpp::base::Countable {
|
||||
public:
|
||||
OBJECT_POOL(IOBuffer_Pool, IOBuffer, 32)
|
||||
SHARED_OBJECT_POOL(Shared_IOBuffer_Pool, IOBuffer, 32)
|
||||
public:
|
||||
/**
|
||||
* Buffer size constant.
|
||||
*/
|
||||
static const v_buff_size BUFFER_SIZE;
|
||||
private:
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getBufferPool() {
|
||||
static auto pool = new oatpp::base::memory::ThreadDistributedMemoryPool("IOBuffer_Buffer_Pool", BUFFER_SIZE, 16);
|
||||
return *pool;
|
||||
}
|
||||
private:
|
||||
void* m_entry;
|
||||
p_char8 m_entry;
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "ObjectMapper.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping {
|
||||
|
||||
@ -37,7 +37,7 @@ const ObjectMapper::Info& ObjectMapper::getInfo() const {
|
||||
}
|
||||
|
||||
oatpp::String ObjectMapper::writeToString(const type::Void& variant) const {
|
||||
stream::ChunkedBuffer stream;
|
||||
stream::BufferOutputStream stream;
|
||||
write(&stream, variant);
|
||||
return stream.toString();
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "./Vector.hpp"
|
||||
#include "./UnorderedSet.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "./Type.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -1,339 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "ChunkedBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
data::stream::DefaultInitializedContext ChunkedBuffer::DEFAULT_CONTEXT(data::stream::StreamType::STREAM_INFINITE);
|
||||
|
||||
const char* ChunkedBuffer::ERROR_ASYNC_FAILED_TO_WRITE_ALL_DATA = "ERROR_ASYNC_FAILED_TO_WRITE_ALL_DATA";
|
||||
|
||||
const char* const ChunkedBuffer::CHUNK_POOL_NAME = "ChunkedBuffer_Chunk_Pool";
|
||||
|
||||
const v_buff_size ChunkedBuffer::CHUNK_ENTRY_SIZE_INDEX_SHIFT = 11;
|
||||
const v_buff_size ChunkedBuffer::CHUNK_ENTRY_SIZE =
|
||||
(1 << ChunkedBuffer::CHUNK_ENTRY_SIZE_INDEX_SHIFT);
|
||||
const v_buff_size ChunkedBuffer::CHUNK_CHUNK_SIZE = 32;
|
||||
|
||||
ChunkedBuffer::ChunkedBuffer()
|
||||
: m_size(0)
|
||||
, m_chunkPos(0)
|
||||
, m_firstEntry(nullptr)
|
||||
, m_lastEntry(nullptr)
|
||||
, m_ioMode(IOMode::ASYNCHRONOUS)
|
||||
{}
|
||||
|
||||
ChunkedBuffer::~ChunkedBuffer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
v_io_size ChunkedBuffer::writeToEntry(ChunkEntry* entry,
|
||||
const void *data,
|
||||
v_buff_size count,
|
||||
v_buff_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, (size_t)count);
|
||||
outChunkPos = count;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
v_io_size ChunkedBuffer::writeToEntryFrom(ChunkEntry* entry,
|
||||
v_buff_size inChunkPos,
|
||||
const void *data,
|
||||
v_buff_size count,
|
||||
v_buff_size& outChunkPos)
|
||||
{
|
||||
v_io_size spaceLeft = CHUNK_ENTRY_SIZE - inChunkPos;
|
||||
if(count >= spaceLeft){
|
||||
std::memcpy(&((p_char8) entry->chunk)[inChunkPos], data, (size_t)spaceLeft);
|
||||
outChunkPos = 0;
|
||||
return spaceLeft;
|
||||
} else {
|
||||
std::memcpy(&((p_char8) entry->chunk)[inChunkPos], data, (size_t)count);
|
||||
outChunkPos = inChunkPos + count;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkedBuffer::ChunkEntry* ChunkedBuffer::getChunkForPosition(ChunkEntry* fromChunk,
|
||||
v_buff_size pos,
|
||||
v_buff_size& outChunkPos)
|
||||
{
|
||||
|
||||
v_buff_size segIndex = pos >> CHUNK_ENTRY_SIZE_INDEX_SHIFT;
|
||||
outChunkPos = pos - (segIndex << CHUNK_ENTRY_SIZE_INDEX_SHIFT);
|
||||
|
||||
auto curr = fromChunk;
|
||||
|
||||
for(v_buff_size i = 0; i < segIndex; i++){
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
return curr;
|
||||
|
||||
}
|
||||
|
||||
v_io_size ChunkedBuffer::write(const void *data, v_buff_size count, async::Action& action){
|
||||
|
||||
(void) action;
|
||||
|
||||
if(count <= 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(m_lastEntry == nullptr){
|
||||
obtainNewEntry();
|
||||
}
|
||||
|
||||
ChunkEntry* entry = m_lastEntry;
|
||||
v_buff_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;
|
||||
|
||||
}
|
||||
|
||||
void ChunkedBuffer::setOutputStreamIOMode(IOMode ioMode) {
|
||||
m_ioMode = ioMode;
|
||||
}
|
||||
|
||||
IOMode ChunkedBuffer::getOutputStreamIOMode() {
|
||||
return m_ioMode;
|
||||
}
|
||||
|
||||
Context& ChunkedBuffer::getOutputStreamContext() {
|
||||
return DEFAULT_CONTEXT;
|
||||
}
|
||||
|
||||
v_io_size ChunkedBuffer::readSubstring(void *buffer,
|
||||
v_buff_size pos,
|
||||
v_buff_size count)
|
||||
{
|
||||
|
||||
if(pos < 0 || pos >= m_size){
|
||||
return 0;
|
||||
}
|
||||
|
||||
v_buff_size countToRead;
|
||||
if(pos + count > m_size){
|
||||
countToRead = m_size - pos;
|
||||
} else {
|
||||
countToRead = count;
|
||||
}
|
||||
|
||||
v_buff_size firstChunkPos;
|
||||
auto firstChunk = getChunkForPosition(m_firstEntry, pos, firstChunkPos);
|
||||
|
||||
v_buff_size lastChunkPos;
|
||||
auto lastChunk = getChunkForPosition(firstChunk, firstChunkPos + countToRead, lastChunkPos);
|
||||
|
||||
v_io_size bufferPos = 0;
|
||||
|
||||
if(firstChunk != lastChunk){
|
||||
|
||||
v_buff_size countToCopy = CHUNK_ENTRY_SIZE - firstChunkPos;
|
||||
std::memcpy(buffer, &((p_char8)firstChunk->chunk)[firstChunkPos], (size_t)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, (size_t)lastChunkPos);
|
||||
|
||||
} else {
|
||||
v_buff_size countToCopy = lastChunkPos - firstChunkPos;
|
||||
std::memcpy(buffer, &((p_char8)firstChunk->chunk)[firstChunkPos], (size_t)countToCopy);
|
||||
}
|
||||
|
||||
return countToRead;
|
||||
|
||||
}
|
||||
|
||||
oatpp::String ChunkedBuffer::getSubstring(v_buff_size pos, v_buff_size count){
|
||||
auto str = oatpp::String((v_int32) count);
|
||||
readSubstring((p_char8)str->data(), pos, count);
|
||||
return str;
|
||||
}
|
||||
|
||||
bool ChunkedBuffer::flushToStream(OutputStream* stream){
|
||||
v_io_size pos = m_size;
|
||||
auto curr = m_firstEntry;
|
||||
while (pos > 0) {
|
||||
if(pos > CHUNK_ENTRY_SIZE) {
|
||||
auto res = stream->writeExactSizeDataSimple(curr->chunk, CHUNK_ENTRY_SIZE);
|
||||
if(res != CHUNK_ENTRY_SIZE) {
|
||||
return false;
|
||||
}
|
||||
pos -= res;
|
||||
} else {
|
||||
auto res = stream->writeExactSizeDataSimple(curr->chunk, pos);
|
||||
if(res != pos) {
|
||||
return false;
|
||||
}
|
||||
pos -= res;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
oatpp::async::CoroutineStarter ChunkedBuffer::flushToStreamAsync(const std::shared_ptr<OutputStream>& stream) {
|
||||
|
||||
class FlushCoroutine : public oatpp::async::Coroutine<FlushCoroutine> {
|
||||
private:
|
||||
std::shared_ptr<ChunkedBuffer> m_chunkedBuffer;
|
||||
std::shared_ptr<OutputStream> m_stream;
|
||||
ChunkEntry* m_currEntry;
|
||||
v_io_size m_bytesLeft;
|
||||
Action m_nextAction;
|
||||
data::buffer::InlineWriteData m_currData;
|
||||
bool m_needInit;
|
||||
public:
|
||||
|
||||
FlushCoroutine(const std::shared_ptr<ChunkedBuffer>& chunkedBuffer,
|
||||
const std::shared_ptr<OutputStream>& stream)
|
||||
: m_chunkedBuffer(chunkedBuffer)
|
||||
, m_stream(stream)
|
||||
, m_currEntry(nullptr)
|
||||
, m_bytesLeft(0)
|
||||
, m_nextAction(Action::createActionByType(Action::TYPE_FINISH))
|
||||
, m_needInit(true)
|
||||
{}
|
||||
|
||||
Action act() override {
|
||||
|
||||
if (m_needInit) {
|
||||
m_needInit = false;
|
||||
m_currEntry = m_chunkedBuffer->m_firstEntry;
|
||||
m_bytesLeft = m_chunkedBuffer->m_size;
|
||||
}
|
||||
|
||||
if(m_currEntry == nullptr) {
|
||||
return finish();
|
||||
}
|
||||
|
||||
if(m_bytesLeft > CHUNK_ENTRY_SIZE) {
|
||||
m_currData.set(m_currEntry->chunk, CHUNK_ENTRY_SIZE);
|
||||
m_nextAction = yieldTo(&FlushCoroutine::act);
|
||||
m_currEntry = m_currEntry->next;
|
||||
m_bytesLeft -= m_currData.bytesLeft;
|
||||
return yieldTo(&FlushCoroutine::writeCurrData);
|
||||
} else {
|
||||
m_currData.set(m_currEntry->chunk, m_bytesLeft);
|
||||
m_nextAction = yieldTo(&FlushCoroutine::act);
|
||||
m_currEntry = m_currEntry->next;
|
||||
m_bytesLeft -= m_currData.bytesLeft;
|
||||
return yieldTo(&FlushCoroutine::writeCurrData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Action writeCurrData() {
|
||||
return m_stream->writeExactSizeDataAsyncInline(m_currData, Action::clone(m_nextAction));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return FlushCoroutine::start(shared_from_this(), stream);
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<ChunkedBuffer::Chunks> ChunkedBuffer::getChunks() {
|
||||
auto chunks = std::make_shared<Chunks>();
|
||||
auto curr = m_firstEntry;
|
||||
v_int32 count = 0;
|
||||
while (curr != nullptr) {
|
||||
chunks->push_back(Chunk::createShared(curr->chunk, curr->next
|
||||
? CHUNK_ENTRY_SIZE
|
||||
: m_size - CHUNK_ENTRY_SIZE * count));
|
||||
++count;
|
||||
curr = curr->next;
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
v_buff_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;
|
||||
|
||||
}
|
||||
|
||||
}}}
|
@ -1,248 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_data_stream_ChunkedBuffer_hpp
|
||||
#define oatpp_data_stream_ChunkedBuffer_hpp
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "Stream.hpp"
|
||||
|
||||
#include "oatpp/core/async/Coroutine.hpp"
|
||||
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
/**
|
||||
* Buffer wich can grow by chunks and implements &id:oatpp::data::stream::ConsistentOutputStream; interface.
|
||||
*/
|
||||
class ChunkedBuffer : public oatpp::base::Countable, public ConsistentOutputStream, public std::enable_shared_from_this<ChunkedBuffer> {
|
||||
public:
|
||||
static data::stream::DefaultInitializedContext DEFAULT_CONTEXT;
|
||||
public:
|
||||
static const char* ERROR_ASYNC_FAILED_TO_WRITE_ALL_DATA;
|
||||
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 v_buff_size CHUNK_ENTRY_SIZE_INDEX_SHIFT;
|
||||
static const v_buff_size CHUNK_ENTRY_SIZE;
|
||||
static const v_buff_size CHUNK_CHUNK_SIZE;
|
||||
|
||||
static oatpp::base::memory::ThreadDistributedMemoryPool& getSegemntPool() {
|
||||
static auto pool = new oatpp::base::memory::ThreadDistributedMemoryPool(CHUNK_POOL_NAME, CHUNK_ENTRY_SIZE, 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::Countable {
|
||||
public:
|
||||
OBJECT_POOL(ChunkedBuffer_Chunk_Pool, Chunk, 32)
|
||||
SHARED_OBJECT_POOL(Shared_ChunkedBuffer_Chunk_Pool, Chunk, 32)
|
||||
public:
|
||||
|
||||
Chunk(void* pData, v_buff_size pSize)
|
||||
: data(pData)
|
||||
, size(pSize)
|
||||
{}
|
||||
|
||||
static std::shared_ptr<Chunk> createShared(void* data, v_buff_size size){
|
||||
return Shared_ChunkedBuffer_Chunk_Pool::allocateShared(data, size);
|
||||
}
|
||||
|
||||
const void* data;
|
||||
const v_buff_size size;
|
||||
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::list<std::shared_ptr<Chunk>> Chunks;
|
||||
private:
|
||||
|
||||
v_buff_size m_size;
|
||||
v_buff_size m_chunkPos;
|
||||
ChunkEntry* m_firstEntry;
|
||||
ChunkEntry* m_lastEntry;
|
||||
IOMode m_ioMode;
|
||||
|
||||
private:
|
||||
|
||||
ChunkEntry* obtainNewEntry();
|
||||
void freeEntry(ChunkEntry* entry);
|
||||
|
||||
v_io_size writeToEntry(ChunkEntry* entry,
|
||||
const void *data,
|
||||
v_buff_size count,
|
||||
v_buff_size& outChunkPos);
|
||||
|
||||
v_io_size writeToEntryFrom(ChunkEntry* entry,
|
||||
v_buff_size inChunkPos,
|
||||
const void *data,
|
||||
v_buff_size count,
|
||||
v_buff_size& outChunkPos);
|
||||
|
||||
ChunkEntry* getChunkForPosition(ChunkEntry* fromChunk,
|
||||
v_buff_size pos,
|
||||
v_buff_size& outChunkPos);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
ChunkedBuffer();
|
||||
|
||||
/**
|
||||
* Virtual Destructor.
|
||||
*/
|
||||
~ChunkedBuffer();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Deleted copy constructor.
|
||||
*/
|
||||
ChunkedBuffer(const ChunkedBuffer&) = delete;
|
||||
|
||||
ChunkedBuffer& operator=(const ChunkedBuffer&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create shared ChunkedBuffer.
|
||||
* @return `std::shared_ptr` to ChunkedBuffer.
|
||||
*/
|
||||
static std::shared_ptr<ChunkedBuffer> createShared(){
|
||||
return Shared_ChunkedBuffer_Pool::allocateShared();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data to ChunkedBuffer. Implementation of &id:oatpp::data::stream::OutputStream::write; method.
|
||||
* @param data - data to write.
|
||||
* @param count - size of data in bytes.
|
||||
* @param action - async specific action. If action is NOT &id:oatpp::async::Action::TYPE_NONE;, then
|
||||
* caller MUST return this action on coroutine iteration.
|
||||
* @return - actual number of bytes written.
|
||||
*/
|
||||
v_io_size write(const void *data, v_buff_size count, async::Action& action) override;
|
||||
|
||||
/**
|
||||
* Set stream I/O mode.
|
||||
* @param ioMode
|
||||
*/
|
||||
void setOutputStreamIOMode(IOMode ioMode) override;
|
||||
|
||||
/**
|
||||
* Set stream I/O mode.
|
||||
* @return
|
||||
*/
|
||||
IOMode getOutputStreamIOMode() override;
|
||||
|
||||
/**
|
||||
* Get stream context.
|
||||
* @return - &id:oatpp::data::stream::Context;.
|
||||
*/
|
||||
Context& getOutputStreamContext() override;
|
||||
|
||||
/**
|
||||
* Read part of ChunkedBuffer to buffer.
|
||||
* @param buffer - buffer to write data to.
|
||||
* @param pos - starting position in ChunkedBuffer to read data from.
|
||||
* @param count - number of bytes to read.
|
||||
* @return - actual number of bytes read from ChunkedBuffer and written to buffer.
|
||||
*/
|
||||
v_io_size readSubstring(void *buffer, v_buff_size pos, v_buff_size count);
|
||||
|
||||
/**
|
||||
* Create &id:oatpp::String; from part of ChunkedBuffer.
|
||||
* @param pos - starting position in ChunkedBuffer.
|
||||
* @param count - size of bytes to write to substring.
|
||||
* @return - &id:oatpp::String;
|
||||
*/
|
||||
oatpp::String getSubstring(v_buff_size pos, v_buff_size count);
|
||||
|
||||
/**
|
||||
* Create &id:oatpp::String; from all data in ChunkedBuffer.
|
||||
* @return - &id:oatpp::String;
|
||||
*/
|
||||
oatpp::String toString() {
|
||||
return getSubstring(0, m_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all data from ChunkedBuffer to &id:oatpp::data::stream::OutputStream;.
|
||||
* ChunkedBuffer will not be cleared during this call!
|
||||
* @param stream - &id:oatpp::data::stream::OutputStream; stream to write all data to.
|
||||
* @return - `true` if no errors occured. **will be refactored to return actual amount of bytes flushed**.
|
||||
*/
|
||||
bool flushToStream(OutputStream* stream);
|
||||
|
||||
/**
|
||||
* Write all data from ChunkedBuffer to &id:oatpp::data::stream::OutputStream; in asynchronous manner.
|
||||
* @param stream - &id:oatpp::data::stream::OutputStream; stream to write all data to.
|
||||
* @return - &id:oatpp::async::CoroutineStarter;.
|
||||
*/
|
||||
oatpp::async::CoroutineStarter flushToStreamAsync(const std::shared_ptr<OutputStream>& stream);
|
||||
|
||||
std::shared_ptr<Chunks> getChunks();
|
||||
|
||||
/**
|
||||
* Get number of bytes written to ChunkedBuffer.
|
||||
* @return - number of bytes written to ChunkedBuffer.
|
||||
*/
|
||||
v_buff_size getSize();
|
||||
|
||||
/**
|
||||
* Clear data in ChunkedBuffer.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* oatpp_data_stream_ChunkedBuffer_hpp */
|
@ -33,9 +33,6 @@
|
||||
namespace oatpp { namespace data{ namespace stream {
|
||||
|
||||
class OutputStreamBufferedProxy : public oatpp::base::Countable, public OutputStream {
|
||||
public:
|
||||
OBJECT_POOL(OutputStreamBufferedProxy_Pool, OutputStreamBufferedProxy, 32)
|
||||
SHARED_OBJECT_POOL(Shared_OutputStreamBufferedProxy_Pool, OutputStreamBufferedProxy, 32)
|
||||
private:
|
||||
std::shared_ptr<OutputStream> m_outputStream;
|
||||
oatpp::data::share::MemoryLabel m_memoryLabel;
|
||||
@ -50,7 +47,7 @@ public:
|
||||
public:
|
||||
|
||||
static std::shared_ptr<OutputStreamBufferedProxy> createShared(const std::shared_ptr<OutputStream>& outputStream, const oatpp::data::share::MemoryLabel& memoryLabel) {
|
||||
return Shared_OutputStreamBufferedProxy_Pool::allocateShared(outputStream, memoryLabel);
|
||||
return std::make_shared<OutputStreamBufferedProxy>(outputStream, memoryLabel);
|
||||
}
|
||||
|
||||
v_io_size write(const void *data, v_buff_size count, async::Action& action) override;
|
||||
@ -83,9 +80,6 @@ public:
|
||||
};
|
||||
|
||||
class InputStreamBufferedProxy : public oatpp::base::Countable, public BufferedInputStream {
|
||||
public:
|
||||
OBJECT_POOL(InputStreamBufferedProxy_Pool, InputStreamBufferedProxy, 32)
|
||||
SHARED_OBJECT_POOL(Shared_InputStreamBufferedProxy_Pool, InputStreamBufferedProxy, 32)
|
||||
protected:
|
||||
std::shared_ptr<InputStream> m_inputStream;
|
||||
oatpp::data::share::MemoryLabel m_memoryLabel;
|
||||
@ -105,7 +99,7 @@ public:
|
||||
static std::shared_ptr<InputStreamBufferedProxy> createShared(const std::shared_ptr<InputStream>& inputStream,
|
||||
const oatpp::data::share::MemoryLabel& memoryLabel)
|
||||
{
|
||||
return Shared_InputStreamBufferedProxy_Pool::allocateShared(inputStream, memoryLabel, 0, 0, false);
|
||||
return std::make_shared<InputStreamBufferedProxy>(inputStream, memoryLabel, 0, 0, false);
|
||||
}
|
||||
|
||||
static std::shared_ptr<InputStreamBufferedProxy> createShared(const std::shared_ptr<InputStream>& inputStream,
|
||||
@ -114,7 +108,7 @@ public:
|
||||
v_io_size bufferWritePosition,
|
||||
bool bufferCanRead)
|
||||
{
|
||||
return Shared_InputStreamBufferedProxy_Pool::allocateShared(inputStream, memoryLabel, bufferReadPosition, bufferWritePosition, bufferCanRead);
|
||||
return std::make_shared<InputStreamBufferedProxy>(inputStream, memoryLabel, bufferReadPosition, bufferWritePosition, bufferCanRead);
|
||||
}
|
||||
|
||||
v_io_size read(void *data, v_buff_size count, async::Action& action) override;
|
||||
|
@ -122,7 +122,7 @@ void StatefulParser::parseHeaders(Headers& headers) {
|
||||
m_currPartIndex ++;
|
||||
|
||||
auto headersText = m_headersBuffer.toString();
|
||||
m_headersBuffer.clear();
|
||||
m_headersBuffer.setCurrentPosition(0);
|
||||
|
||||
protocol::http::Status status;
|
||||
parser::Caret caret(headersText);
|
||||
@ -246,7 +246,7 @@ StatefulParser::ListenerCall StatefulParser::parseNext_Headers(data::buffer::Inl
|
||||
|
||||
if(m_headerSectionEndAccumulator == HEADERS_SECTION_END) {
|
||||
|
||||
if(m_headersBuffer.getSize() + i > m_maxPartHeadersSize) {
|
||||
if(m_headersBuffer.getCurrentPosition() + i > m_maxPartHeadersSize) {
|
||||
throw std::runtime_error("[oatpp::web::mime::multipart::StatefulParser::parseNext_Headers()]: Error. Too large heades.");
|
||||
}
|
||||
|
||||
@ -264,8 +264,8 @@ StatefulParser::ListenerCall StatefulParser::parseNext_Headers(data::buffer::Inl
|
||||
|
||||
}
|
||||
|
||||
if(m_headersBuffer.getSize() + size > m_maxPartHeadersSize) {
|
||||
throw std::runtime_error("[oatpp::web::mime::multipart::StatefulParser::parseNext_Headers()]: Error. Too large heades.");
|
||||
if(m_headersBuffer.getCurrentPosition() + size > m_maxPartHeadersSize) {
|
||||
throw std::runtime_error("[oatpp::web::mime::multipart::StatefulParser::parseNext_Headers()]: Error. Headers section is too large.");
|
||||
}
|
||||
|
||||
m_headersBuffer.writeSimple(data, size);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#ifndef oatpp_web_mime_multipart_StatefulParser_hpp
|
||||
#define oatpp_web_mime_multipart_StatefulParser_hpp
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
#include "oatpp/core/data/share/LazyStringMap.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
@ -174,7 +174,7 @@ private:
|
||||
/*
|
||||
* Headers of the part are stored in the buffer and are parsed as one chunk.
|
||||
*/
|
||||
oatpp::data::stream::ChunkedBuffer m_headersBuffer;
|
||||
data::stream::BufferOutputStream m_headersBuffer;
|
||||
|
||||
/*
|
||||
* Max length of all headers per one part.
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "./Http.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace protocol { namespace http {
|
||||
@ -138,7 +138,7 @@ const char* const Range::UNIT_BYTES = "bytes";
|
||||
const char* const ContentRange::UNIT_BYTES = "bytes";
|
||||
|
||||
oatpp::String Range::toString() const {
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
data::stream::BufferOutputStream stream(256);
|
||||
stream.writeSimple(units->data(), units->size());
|
||||
stream.writeSimple("=", 1);
|
||||
stream.writeAsString(start);
|
||||
@ -183,7 +183,7 @@ Range Range::parse(const oatpp::String& str) {
|
||||
}
|
||||
|
||||
oatpp::String ContentRange::toString() const {
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
data::stream::BufferOutputStream stream(256);
|
||||
stream.writeSimple(units->data(), units->size());
|
||||
stream.writeSimple(" ", 1);
|
||||
stream.writeAsString(start);
|
||||
|
@ -41,7 +41,7 @@ BodyDecoder::decodeToStringAsync(const Headers& headers,
|
||||
Headers m_headers;
|
||||
std::shared_ptr<data::stream::InputStream> m_bodyStream;
|
||||
std::shared_ptr<data::stream::IOStream> m_connection;
|
||||
std::shared_ptr<data::stream::ChunkedBuffer> m_outputStream;
|
||||
std::shared_ptr<data::stream::BufferOutputStream> m_outputStream;
|
||||
public:
|
||||
|
||||
ToStringDecoder(const BodyDecoder* decoder,
|
||||
@ -52,7 +52,7 @@ BodyDecoder::decodeToStringAsync(const Headers& headers,
|
||||
, m_headers(headers)
|
||||
, m_bodyStream(bodyStream)
|
||||
, m_connection(connection)
|
||||
, m_outputStream(std::make_shared<data::stream::ChunkedBuffer>())
|
||||
, m_outputStream(std::make_shared<data::stream::BufferOutputStream>())
|
||||
{}
|
||||
|
||||
Action act() override {
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include "oatpp/web/protocol/http/Http.hpp"
|
||||
#include "oatpp/core/data/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
#include "oatpp/core/async/Coroutine.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming {
|
||||
@ -49,7 +49,7 @@ private:
|
||||
std::shared_ptr<data::stream::InputStream> m_bodyStream;
|
||||
std::shared_ptr<data::stream::IOStream> m_connection;
|
||||
std::shared_ptr<data::mapping::ObjectMapper> m_objectMapper;
|
||||
std::shared_ptr<data::stream::ChunkedBuffer> m_outputStream;
|
||||
std::shared_ptr<data::stream::BufferOutputStream> m_outputStream;
|
||||
public:
|
||||
|
||||
ToDtoDecoder(const BodyDecoder* decoder,
|
||||
@ -62,7 +62,7 @@ private:
|
||||
, m_bodyStream(bodyStream)
|
||||
, m_connection(connection)
|
||||
, m_objectMapper(objectMapper)
|
||||
, m_outputStream(std::make_shared<data::stream::ChunkedBuffer>())
|
||||
, m_outputStream(std::make_shared<data::stream::BufferOutputStream>())
|
||||
{}
|
||||
|
||||
oatpp::async::Action act() override {
|
||||
@ -125,7 +125,7 @@ public:
|
||||
data::stream::InputStream* bodyStream,
|
||||
data::stream::IOStream* connection) const
|
||||
{
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
decode(headers, bodyStream, &stream, connection);
|
||||
return stream.toString();
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ std::shared_ptr<Request> Request::createShared(const std::shared_ptr<oatpp::data
|
||||
const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
|
||||
const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder)
|
||||
{
|
||||
return Shared_Incoming_Request_Pool::allocateShared(connection, startingLine, headers, bodyStream, bodyDecoder);
|
||||
return std::make_shared<Request>(connection, startingLine, headers, bodyStream, bodyDecoder);
|
||||
}
|
||||
|
||||
std::shared_ptr<oatpp::data::stream::IOStream> Request::getConnection() {
|
||||
|
@ -37,9 +37,6 @@ namespace oatpp { namespace web { namespace protocol { namespace http { namespac
|
||||
* Class http::incoming::Request AKA IncomingRequest represents client's incoming request.
|
||||
*/
|
||||
class Request : public oatpp::base::Countable {
|
||||
public:
|
||||
OBJECT_POOL(Incoming_Request_Pool, Request, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Incoming_Request_Pool, Request, 32)
|
||||
private:
|
||||
|
||||
std::shared_ptr<oatpp::data::stream::IOStream> m_connection;
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include "RequestHeadersReader.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace protocol { namespace http { namespace incoming {
|
||||
|
||||
v_io_size RequestHeadersReader::readHeadersSectionIterative(ReadHeadersIteration& iteration,
|
||||
|
@ -42,8 +42,9 @@ std::shared_ptr<Response> Response::createShared(v_int32 statusCode,
|
||||
const oatpp::String& statusDescription,
|
||||
const http::Headers& headers,
|
||||
const std::shared_ptr<oatpp::data::stream::InputStream>& bodyStream,
|
||||
const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder) {
|
||||
return Shared_Incoming_Response_Pool::allocateShared(statusCode, statusDescription, headers, bodyStream, bodyDecoder);
|
||||
const std::shared_ptr<const http::incoming::BodyDecoder>& bodyDecoder)
|
||||
{
|
||||
return std::make_shared<Response>(statusCode, statusDescription, headers, bodyStream, bodyDecoder);
|
||||
}
|
||||
|
||||
v_int32 Response::getStatusCode() const {
|
||||
|
@ -35,9 +35,6 @@ namespace oatpp { namespace web { namespace protocol { namespace http { namespac
|
||||
* Class http::incoming::Response AKA IncomingResponse represents server's incoming response
|
||||
*/
|
||||
class Response : public oatpp::base::Countable {
|
||||
public:
|
||||
OBJECT_POOL(Incoming_Response_Pool, Response, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Incoming_Response_Pool, Response, 32)
|
||||
private:
|
||||
v_int32 m_statusCode;
|
||||
oatpp::String m_statusDescription;
|
||||
|
@ -34,7 +34,7 @@ BufferBody::BufferBody(const oatpp::String &buffer, const data::share::StringKey
|
||||
|
||||
std::shared_ptr<BufferBody> BufferBody::createShared(const oatpp::String &buffer,
|
||||
const data::share::StringKeyLabel &contentType) {
|
||||
return Shared_Http_Outgoing_BufferBody_Pool::allocateShared(buffer, contentType);
|
||||
return std::make_shared<BufferBody>(buffer, contentType);
|
||||
}
|
||||
|
||||
v_io_size BufferBody::read(void *buffer, v_buff_size count, async::Action &action) {
|
||||
|
@ -35,9 +35,6 @@ namespace oatpp { namespace web { namespace protocol { namespace http { namespac
|
||||
* Implements functionality to use &id::oatpp::String; as data source for http body.
|
||||
*/
|
||||
class BufferBody : public oatpp::base::Countable, public Body {
|
||||
public:
|
||||
OBJECT_POOL(Http_Outgoing_BufferBody_Pool, BufferBody, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Http_Outgoing_BufferBody_Pool, BufferBody, 32)
|
||||
private:
|
||||
oatpp::String m_buffer;
|
||||
oatpp::data::share::StringKeyLabel m_contentType;
|
||||
|
@ -45,7 +45,7 @@ std::shared_ptr<Request> Request::createShared(const oatpp::data::share::StringK
|
||||
const oatpp::data::share::StringKeyLabel& path,
|
||||
const Headers& headers,
|
||||
const std::shared_ptr<Body>& body) {
|
||||
return Shared_Outgoing_Request_Pool::allocateShared(method, path, headers, body);
|
||||
return std::make_shared<Request>(method, path, headers, body);
|
||||
}
|
||||
|
||||
const oatpp::data::share::StringKeyLabel& Request::getMethod() const {
|
||||
|
@ -40,9 +40,6 @@ public:
|
||||
* Convenience typedef for &id:oatpp::web::protocol::http::Headers;.
|
||||
*/
|
||||
typedef protocol::http::Headers Headers;
|
||||
public:
|
||||
OBJECT_POOL(Outgoing_Request_Pool, Request, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Outgoing_Request_Pool, Request, 32)
|
||||
private:
|
||||
oatpp::data::share::StringKeyLabel m_method;
|
||||
oatpp::data::share::StringKeyLabel m_path;
|
||||
|
@ -37,7 +37,7 @@ Response::Response(const Status& status,
|
||||
|
||||
std::shared_ptr<Response> Response::createShared(const Status& status,
|
||||
const std::shared_ptr<Body>& body) {
|
||||
return Shared_Outgoing_Response_Pool::allocateShared(status, body);
|
||||
return std::make_shared<Response>(status, body);
|
||||
}
|
||||
|
||||
const Status& Response::getStatus() const {
|
||||
|
@ -53,9 +53,6 @@ public:
|
||||
* Convenience typedef for &id:oatpp::network::ConnectionHandler;.
|
||||
*/
|
||||
typedef oatpp::network::ConnectionHandler ConnectionHandler;
|
||||
public:
|
||||
OBJECT_POOL(Outgoing_Response_Pool, Response, 32)
|
||||
SHARED_OBJECT_POOL(Shared_Outgoing_Response_Pool, Response, 32)
|
||||
private:
|
||||
Status m_status;
|
||||
Headers m_headers;
|
||||
|
@ -29,7 +29,6 @@
|
||||
|
||||
#include "oatpp/core/data/mapping/ObjectMapper.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Type.hpp"
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace protocol { namespace http { namespace outgoing {
|
||||
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
#include "Endpoint.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace server { namespace api {
|
||||
|
||||
Endpoint::Info::Param::Param()
|
||||
@ -63,7 +61,7 @@ std::shared_ptr<Endpoint::Info> Endpoint::Info::createShared(){
|
||||
}
|
||||
|
||||
oatpp::String Endpoint::Info::toString() {
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
|
||||
stream << "\nEndpoint\n";
|
||||
|
||||
|
@ -35,12 +35,12 @@ AuthorizationHandler::AuthorizationHandler(const oatpp::String& scheme, const oa
|
||||
, m_realm(realm)
|
||||
{}
|
||||
|
||||
void AuthorizationHandler::renderAuthenticateHeaderValue(ChunkedBuffer& stream) {
|
||||
void AuthorizationHandler::renderAuthenticateHeaderValue(BufferOutputStream& stream) {
|
||||
stream << m_scheme << " " << "realm=\"" << m_realm << "\"";
|
||||
}
|
||||
|
||||
void AuthorizationHandler::addErrorResponseHeaders(Headers& headers) {
|
||||
ChunkedBuffer stream;
|
||||
BufferOutputStream stream;
|
||||
renderAuthenticateHeaderValue(stream);
|
||||
headers.put_LockFree(protocol::http::Header::WWW_AUTHENTICATE, stream.toString());
|
||||
}
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include "oatpp/web/protocol/http/Http.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/data/mapping/type/Type.hpp"
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
|
||||
|
||||
namespace oatpp { namespace web { namespace server { namespace handler {
|
||||
|
||||
@ -54,9 +52,9 @@ public:
|
||||
typedef oatpp::web::server::handler::AuthorizationObject AuthorizationObject;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::data::stream::ChunkedBuffer;.
|
||||
* Convenience typedef for &id:oatpp::data::stream::BufferOutputStream;.
|
||||
*/
|
||||
typedef oatpp::data::stream::ChunkedBuffer ChunkedBuffer;
|
||||
typedef oatpp::data::stream::BufferOutputStream BufferOutputStream;
|
||||
|
||||
/**
|
||||
* Convenience typedef for &id:oatpp::web::protocol::http::Headers;.
|
||||
@ -89,9 +87,9 @@ public:
|
||||
/**
|
||||
* Render WWW-Authenicate header value. <br>
|
||||
* Custom Authorization handlers may override this method in order to provide additional information.
|
||||
* @param stream - &id:oatpp::data::stream::ChunkedBuffer;.
|
||||
* @param stream - &id:oatpp::data::stream::BufferOutputStream;.
|
||||
*/
|
||||
virtual void renderAuthenticateHeaderValue(ChunkedBuffer& stream);
|
||||
virtual void renderAuthenticateHeaderValue(BufferOutputStream& stream);
|
||||
|
||||
/**
|
||||
* Add authorization error headers to the headers map. <br>
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "Pattern.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
|
||||
namespace oatpp { namespace web { namespace url { namespace mapping {
|
||||
|
||||
@ -182,20 +182,20 @@ bool Pattern::match(const StringKeyLabel& url, MatchMap& matchMap) {
|
||||
}
|
||||
|
||||
oatpp::String Pattern::toString() {
|
||||
auto stream = oatpp::data::stream::ChunkedBuffer::createShared();
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
for (const std::shared_ptr<Part>& part : *m_parts) {
|
||||
if(part->function == Part::FUNCTION_CONST) {
|
||||
stream->writeSimple("/", 1);
|
||||
stream->writeSimple(part->text);
|
||||
stream.writeSimple("/", 1);
|
||||
stream.writeSimple(part->text);
|
||||
} else if(part->function == Part::FUNCTION_VAR) {
|
||||
stream->writeSimple("/{", 2);
|
||||
stream->writeSimple(part->text);
|
||||
stream->writeSimple("}", 1);
|
||||
stream.writeSimple("/{", 2);
|
||||
stream.writeSimple(part->text);
|
||||
stream.writeSimple("}", 1);
|
||||
} else if(part->function == Part::FUNCTION_ANY_END) {
|
||||
stream->writeSimple("/*", 2);
|
||||
stream.writeSimple("/*", 2);
|
||||
}
|
||||
}
|
||||
return stream->toString();
|
||||
return stream.toString();
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
@ -7,10 +7,6 @@ add_executable(oatppAllTests
|
||||
oatpp/core/base/CommandLineArgumentsTest.hpp
|
||||
oatpp/core/base/LoggerTest.cpp
|
||||
oatpp/core/base/LoggerTest.hpp
|
||||
oatpp/core/base/memory/MemoryPoolTest.cpp
|
||||
oatpp/core/base/memory/MemoryPoolTest.hpp
|
||||
oatpp/core/base/memory/PerfTest.cpp
|
||||
oatpp/core/base/memory/PerfTest.hpp
|
||||
oatpp/core/data/buffer/ProcessorTest.cpp
|
||||
oatpp/core/data/buffer/ProcessorTest.hpp
|
||||
oatpp/core/data/mapping/type/AnyTest.cpp
|
||||
@ -51,8 +47,6 @@ add_executable(oatppAllTests
|
||||
oatpp/core/data/share/StringTemplateTest.hpp
|
||||
oatpp/core/data/stream/BufferStreamTest.cpp
|
||||
oatpp/core/data/stream/BufferStreamTest.hpp
|
||||
oatpp/core/data/stream/ChunkedBufferTest.cpp
|
||||
oatpp/core/data/stream/ChunkedBufferTest.hpp
|
||||
oatpp/core/parser/CaretTest.cpp
|
||||
oatpp/core/parser/CaretTest.hpp
|
||||
oatpp/core/provider/PoolTest.cpp
|
||||
|
@ -50,14 +50,11 @@
|
||||
#include "oatpp/core/data/resource/InMemoryDataTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/BufferStreamTest.hpp"
|
||||
#include "oatpp/core/data/stream/ChunkedBufferTest.hpp"
|
||||
#include "oatpp/core/data/share/LazyStringMapTest.hpp"
|
||||
#include "oatpp/core/data/share/StringTemplateTest.hpp"
|
||||
#include "oatpp/core/data/share/MemoryLabelTest.hpp"
|
||||
#include "oatpp/core/data/buffer/ProcessorTest.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/MemoryPoolTest.hpp"
|
||||
#include "oatpp/core/base/memory/PerfTest.hpp"
|
||||
#include "oatpp/core/base/CommandLineArgumentsTest.hpp"
|
||||
#include "oatpp/core/base/LoggerTest.hpp"
|
||||
|
||||
@ -86,20 +83,15 @@ void runTests() {
|
||||
i ++;
|
||||
}
|
||||
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
|
||||
OATPP_RUN_TEST(oatpp::test::base::LoggerTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::memory::MemoryPoolTest);
|
||||
OATPP_RUN_TEST(oatpp::test::memory::PerfTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::share::MemoryLabelTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::share::LazyStringMapTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::share::StringTemplateTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::buffer::ProcessorTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::stream::ChunkedBufferTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::stream::BufferStreamTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::ObjectWrapperTest);
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "LockTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
|
||||
#include "oatpp/core/async/Executor.hpp"
|
||||
#include "oatpp/core/async/Lock.hpp"
|
||||
@ -40,11 +40,11 @@ static constexpr v_int32 NUM_SYMBOLS = 20;
|
||||
|
||||
class Buff {
|
||||
private:
|
||||
oatpp::data::stream::ChunkedBuffer *m_buffer;
|
||||
oatpp::data::stream::BufferOutputStream *m_buffer;
|
||||
std::mutex m_mutex;
|
||||
public:
|
||||
|
||||
Buff(oatpp::data::stream::ChunkedBuffer *buffer)
|
||||
Buff(oatpp::data::stream::BufferOutputStream *buffer)
|
||||
: m_buffer(buffer) {}
|
||||
|
||||
void writeChar(char c) {
|
||||
@ -168,7 +168,7 @@ bool checkSymbol(char symbol, const oatpp::String& str) {
|
||||
void LockTest::onRun() {
|
||||
|
||||
oatpp::async::Lock lock;
|
||||
oatpp::data::stream::ChunkedBuffer buffer;
|
||||
oatpp::data::stream::BufferOutputStream buffer;
|
||||
Buff buff(&buffer);
|
||||
|
||||
oatpp::async::Executor executor(10, 1, 1);
|
||||
|
@ -1,199 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "MemoryPoolTest.hpp"
|
||||
|
||||
#include "oatpp/core/base/memory/MemoryPool.hpp"
|
||||
#include "oatpp-test/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){
|
||||
|
||||
(void)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);
|
||||
#ifndef OATPP_DISABLE_POOL_ALLOCATIONS
|
||||
for(v_int32 i = 0; i < objectsNumber; i++){
|
||||
OATPP_ASSERT(objects[i]->a == -100);
|
||||
}
|
||||
#else
|
||||
OATPP_LOGW("TEST[base::memory::MemoryPoolTest]", "WARNING. 'OATPP_DISABLE_POOL_ALLOCATIONS' flag is ON. Assertions disabled.");
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}
|
@ -1,45 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef test_memory_MemoryPoolTest_hpp
|
||||
#define test_memory_MemoryPoolTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace memory {
|
||||
|
||||
/**
|
||||
* Test memory pool allocations
|
||||
*/
|
||||
class MemoryPoolTest : public UnitTest{
|
||||
public:
|
||||
|
||||
MemoryPoolTest():UnitTest("TEST[base::memory::MemoryPoolTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* test_memory_MemoryPoolTest_hpp */
|
@ -1,109 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "PerfTest.hpp"
|
||||
|
||||
#include "oatpp/core/Types.hpp"
|
||||
#include "oatpp/core/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)){
|
||||
oatpp::base::Environment::log(2, "PerfTest::TestBase", "[ERROR|CRITICAL]: MemoryPool malfunction. Deleting object of wrong size"); \
|
||||
}
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class TestChild : public oatpp::base::Countable, 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) {
|
||||
(void)sz;
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Task : public oatpp::base::Countable {
|
||||
private:
|
||||
std::shared_ptr<TestBase> m_shared;
|
||||
public:
|
||||
|
||||
Task(const std::shared_ptr<TestBase>& shared)
|
||||
: m_shared(shared)
|
||||
{}
|
||||
|
||||
void run() {
|
||||
for(v_int32 i = 0; i < 10; i ++) {
|
||||
std::shared_ptr<TestBase> shared(new TestChild());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void PerfTest::onRun() {
|
||||
|
||||
v_int32 iterations = 1;
|
||||
v_int32 threadCount = 100;
|
||||
|
||||
for(int i = 0; i < iterations; i++) {
|
||||
|
||||
std::list<std::thread> threads;
|
||||
|
||||
for(v_int32 n = 0; n < threadCount; n++) {
|
||||
std::shared_ptr<TestBase> shared;
|
||||
threads.push_back(std::thread(&Task::run, Task(shared)));
|
||||
}
|
||||
|
||||
for(auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}
|
@ -1,42 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PerfTest_hpp
|
||||
#define PerfTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace memory {
|
||||
|
||||
class PerfTest : public UnitTest{
|
||||
public:
|
||||
|
||||
PerfTest():UnitTest("TEST[base::memory::PerfTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif /* PerfTest_hpp */
|
@ -1,129 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "ChunkedBufferTest.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace stream {
|
||||
|
||||
void ChunkedBufferTest::onRun() {
|
||||
|
||||
typedef oatpp::data::stream::ChunkedBuffer ChunkedBuffer;
|
||||
|
||||
{
|
||||
ChunkedBuffer stream;
|
||||
|
||||
stream << "int=" << 1 << ", float=" << 1.1 << ", "
|
||||
<< "bool=" << true << " or " << false;
|
||||
|
||||
OATPP_LOGV(TAG, "str='%s'", stream.toString()->c_str());
|
||||
|
||||
stream.clear();
|
||||
stream << 101;
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(101));
|
||||
|
||||
stream.clear();
|
||||
stream << (v_float32)101.1;
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float32ToStr(101.1f));
|
||||
|
||||
stream.clear();
|
||||
stream << (v_float64)101.1;
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float64ToStr(101.1));
|
||||
|
||||
stream.clear();
|
||||
stream << true;
|
||||
OATPP_ASSERT(stream.toString() == "true");
|
||||
|
||||
stream.clear();
|
||||
stream << false;
|
||||
OATPP_ASSERT(stream.toString() == "false");
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::String("oat++");
|
||||
OATPP_ASSERT(stream.toString() == "oat++");
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Int8(8);
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(8));
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Int16(16);
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(16));
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Int32(32);
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(32));
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Int64(64);
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::int32ToStr(64));
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Float32(0.32f);
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float32ToStr(0.32f));
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Float64(0.64);
|
||||
OATPP_ASSERT(stream.toString() == oatpp::utils::conversion::float64ToStr(0.64));
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Boolean(true);
|
||||
OATPP_ASSERT(stream.toString() == "true");
|
||||
|
||||
stream.clear();
|
||||
stream << oatpp::Boolean(false);
|
||||
OATPP_ASSERT(stream.toString() == "false");
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
ChunkedBuffer stream;
|
||||
|
||||
for(v_int32 i = 0; i < ChunkedBuffer::CHUNK_ENTRY_SIZE * 10; i++) {
|
||||
stream.writeSimple("0123456789", 10);
|
||||
}
|
||||
|
||||
auto wholeText = stream.toString();
|
||||
|
||||
OATPP_ASSERT(wholeText->size() == ChunkedBuffer::CHUNK_ENTRY_SIZE * 10 * 10);
|
||||
|
||||
v_int32 substringSize = 10;
|
||||
for(v_int32 i = 0; i < wholeText->size() - substringSize; i ++) {
|
||||
OATPP_ASSERT(oatpp::String(&wholeText->data()[i], substringSize) == stream.getSubstring(i, substringSize));
|
||||
}
|
||||
|
||||
substringSize = (v_int32) ChunkedBuffer::CHUNK_ENTRY_SIZE * 2;
|
||||
for(v_int32 i = 0; i < wholeText->size() - substringSize; i ++) {
|
||||
OATPP_ASSERT(oatpp::String(&wholeText->data()[i], substringSize) == stream.getSubstring(i, substringSize));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}}}}}
|
@ -1,43 +0,0 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_test_core_data_stream_ChunkedBufferTest_hpp
|
||||
#define oatpp_test_core_data_stream_ChunkedBufferTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace stream {
|
||||
|
||||
class ChunkedBufferTest : public UnitTest{
|
||||
public:
|
||||
|
||||
ChunkedBufferTest():UnitTest("TEST[core::data::stream::ChunkedBufferTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}
|
||||
|
||||
|
||||
#endif //oatpp_test_core_data_stream_ChunkedBufferTest_hpp
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include "oatpp/network/virtual_/Interface.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <list>
|
||||
@ -59,11 +59,11 @@ namespace {
|
||||
OATPP_ASSERT(res == m_dataSample->size());
|
||||
|
||||
v_char8 buffer[100];
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
res = oatpp::data::stream::transfer(socket.get(), &stream, 2, buffer, 100);
|
||||
|
||||
OATPP_ASSERT(res == 2);
|
||||
OATPP_ASSERT(stream.getSize() == res);
|
||||
OATPP_ASSERT(stream.getCurrentPosition() == res);
|
||||
OATPP_ASSERT(stream.toString() == "OK");
|
||||
|
||||
//OATPP_LOGV("client", "finished - OK");
|
||||
@ -86,11 +86,11 @@ namespace {
|
||||
|
||||
void run() {
|
||||
v_char8 buffer[100];
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
auto res = oatpp::data::stream::transfer(m_socket.get(), &stream, m_dataSample->size(), buffer, 100);
|
||||
|
||||
OATPP_ASSERT(res == m_dataSample->size());
|
||||
OATPP_ASSERT(stream.getSize() == res);
|
||||
OATPP_ASSERT(stream.getCurrentPosition() == res);
|
||||
OATPP_ASSERT(stream.toString() == m_dataSample);
|
||||
|
||||
res = m_socket->writeExactSizeDataSimple("OK", 2);
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include "oatpp/network/virtual_/Pipe.hpp"
|
||||
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/data/stream/BufferStream.hpp"
|
||||
|
||||
#include "oatpp-test/Checker.hpp"
|
||||
|
||||
@ -73,12 +73,12 @@ namespace {
|
||||
|
||||
class ReaderTask : public oatpp::base::Countable {
|
||||
private:
|
||||
std::shared_ptr<oatpp::data::stream::ChunkedBuffer> m_buffer;
|
||||
std::shared_ptr<oatpp::data::stream::BufferOutputStream> m_buffer;
|
||||
std::shared_ptr<Pipe> m_pipe;
|
||||
v_int64 m_chunksToTransfer;
|
||||
public:
|
||||
|
||||
ReaderTask(const std::shared_ptr<oatpp::data::stream::ChunkedBuffer> &buffer,
|
||||
ReaderTask(const std::shared_ptr<oatpp::data::stream::BufferOutputStream> &buffer,
|
||||
const std::shared_ptr<Pipe>& pipe,
|
||||
v_int64 chunksToTransfer)
|
||||
: m_buffer(buffer)
|
||||
@ -88,13 +88,13 @@ namespace {
|
||||
|
||||
void run() {
|
||||
v_char8 readBuffer[256];
|
||||
while (m_buffer->getSize() < CHUNK_SIZE * m_chunksToTransfer) {
|
||||
while (m_buffer->getCurrentPosition() < CHUNK_SIZE * m_chunksToTransfer) {
|
||||
auto res = m_pipe->getReader()->readSimple(readBuffer, 256);
|
||||
if(res > 0) {
|
||||
m_buffer->writeSimple(readBuffer, res);
|
||||
}
|
||||
}
|
||||
OATPP_LOGV("ReaderTask", "sent %d bytes", m_buffer->getSize());
|
||||
OATPP_LOGV("ReaderTask", "sent %d bytes", m_buffer->getCurrentPosition());
|
||||
}
|
||||
|
||||
};
|
||||
@ -103,7 +103,7 @@ namespace {
|
||||
|
||||
OATPP_LOGV("transfer", "writer-nb: %d, reader-nb: %d", writeNonBlock, readerNonBlock);
|
||||
|
||||
auto buffer = oatpp::data::stream::ChunkedBuffer::createShared();
|
||||
auto buffer = std::make_shared<oatpp::data::stream::BufferOutputStream>();
|
||||
|
||||
{
|
||||
|
||||
@ -117,9 +117,9 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
OATPP_ASSERT(buffer->getSize() == chunksToTransfer * CHUNK_SIZE);
|
||||
OATPP_ASSERT(buffer->getCurrentPosition() == chunksToTransfer * CHUNK_SIZE);
|
||||
|
||||
auto ruleBuffer = oatpp::data::stream::ChunkedBuffer::createShared();
|
||||
auto ruleBuffer = std::make_shared<oatpp::data::stream::BufferOutputStream>();
|
||||
for(v_int32 i = 0; i < chunksToTransfer; i ++) {
|
||||
ruleBuffer->writeSimple(DATA_CHUNK, CHUNK_SIZE);
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ private:
|
||||
public:
|
||||
|
||||
Action act() override {
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
for(v_int32 i = 0; i < oatpp::data::buffer::IOBuffer::BUFFER_SIZE; i++) {
|
||||
stream.writeSimple("0123456789", 10);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ void FullAsyncTest::onRun() {
|
||||
}
|
||||
|
||||
{ // test Big Echo with body
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
for(v_int32 i = 0; i < oatpp::data::buffer::IOBuffer::BUFFER_SIZE; i++) {
|
||||
stream.writeSimple("0123456789", 10);
|
||||
}
|
||||
@ -215,7 +215,7 @@ void FullAsyncTest::onRun() {
|
||||
{ // test Chunked body
|
||||
oatpp::String sample = "__abcdefghijklmnopqrstuvwxyz-0123456789";
|
||||
v_int32 numIterations = 10;
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
for(v_int32 i = 0; i < numIterations; i++) {
|
||||
stream.writeSimple(sample->data(), sample->size());
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ void FullTest::onRun() {
|
||||
}
|
||||
|
||||
{ // test Big Echo with body
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
for(v_int32 i = 0; i < oatpp::data::buffer::IOBuffer::BUFFER_SIZE; i++) {
|
||||
stream.writeSimple("0123456789", 10);
|
||||
}
|
||||
@ -433,7 +433,7 @@ void FullTest::onRun() {
|
||||
{ // test Chunked body
|
||||
oatpp::String sample = "__abcdefghijklmnopqrstuvwxyz-0123456789";
|
||||
v_int32 numIterations = 10;
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
for(v_int32 i = 0; i < numIterations; i++) {
|
||||
stream.writeSimple(sample->data(), sample->size());
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ void PipelineAsyncTest::onRun() {
|
||||
|
||||
std::thread pipeInThread([this, connection] {
|
||||
|
||||
oatpp::data::stream::ChunkedBuffer pipelineStream;
|
||||
oatpp::data::stream::BufferOutputStream pipelineStream;
|
||||
|
||||
for (v_int32 i = 0; i < m_pipelineSize; i++) {
|
||||
pipelineStream << SAMPLE_IN;
|
||||
@ -160,7 +160,7 @@ void PipelineAsyncTest::onRun() {
|
||||
std::thread pipeOutThread([this, connection] {
|
||||
|
||||
oatpp::String sample = SAMPLE_OUT;
|
||||
oatpp::data::stream::ChunkedBuffer receiveStream;
|
||||
oatpp::data::stream::BufferOutputStream receiveStream;
|
||||
oatpp::data::buffer::IOBuffer ioBuffer;
|
||||
|
||||
auto res = oatpp::data::stream::transfer(connection.object.get(), &receiveStream, sample->size() * m_pipelineSize, ioBuffer.getData(), ioBuffer.getSize());
|
||||
|
@ -138,7 +138,7 @@ void PipelineTest::onRun() {
|
||||
|
||||
std::thread pipeInThread([this, connection] {
|
||||
|
||||
oatpp::data::stream::ChunkedBuffer pipelineStream;
|
||||
oatpp::data::stream::BufferOutputStream pipelineStream;
|
||||
|
||||
for (v_int32 i = 0; i < m_pipelineSize; i++) {
|
||||
pipelineStream << SAMPLE_IN;
|
||||
|
@ -88,7 +88,7 @@ namespace {
|
||||
v_int64 bufferSize = 16;
|
||||
std::unique_ptr<v_char8[]> buffer(new v_char8[bufferSize]);
|
||||
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
oatpp::data::stream::transfer(payload->openInputStream(), &stream, 0, buffer.get(), bufferSize);
|
||||
|
||||
oatpp::String readData = stream.toString();
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "ApiControllerTest.hpp"
|
||||
|
||||
#include "oatpp/web/server/api/ApiController.hpp"
|
||||
#include "oatpp/core/data/stream/ChunkedBuffer.hpp"
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace web { namespace server { namespace api {
|
||||
@ -108,7 +107,7 @@ void ApiControllerTest::onRun() {
|
||||
auto response = controller.root();
|
||||
OATPP_ASSERT(response->getStatus().code == 200);
|
||||
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
response->send(&stream, &headersOutBuffer, nullptr);
|
||||
|
||||
OATPP_LOGD(TAG, "response:\n---\n%s\n---\n", stream.toString()->c_str());
|
||||
@ -135,7 +134,7 @@ void ApiControllerTest::onRun() {
|
||||
auto response = controller.pathParams("p1", "p2");
|
||||
OATPP_ASSERT(response->getStatus().code == 200);
|
||||
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
response->send(&stream, &headersOutBuffer, nullptr);
|
||||
|
||||
OATPP_LOGD(TAG, "response:\n---\n%s\n---\n", stream.toString()->c_str());
|
||||
@ -156,7 +155,7 @@ void ApiControllerTest::onRun() {
|
||||
auto response = controller.queryParams("p1", "p2");
|
||||
OATPP_ASSERT(response->getStatus().code == 200);
|
||||
|
||||
oatpp::data::stream::ChunkedBuffer stream;
|
||||
oatpp::data::stream::BufferOutputStream stream;
|
||||
response->send(&stream, &headersOutBuffer, nullptr);
|
||||
|
||||
OATPP_LOGD(TAG, "response:\n---\n%s\n---\n", stream.toString()->c_str());
|
||||
|
Loading…
Reference in New Issue
Block a user