Remove memory pools. Remove ChunkedBuffer.

This commit is contained in:
lganzzzo 2021-11-16 01:45:15 +02:00
parent 97d7597112
commit 5d2f8693eb
57 changed files with 76 additions and 2305 deletions

View File

@ -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

View File

@ -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);

View File

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

View File

@ -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)
{}
}}}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(){

View File

@ -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.

View File

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

View File

@ -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 {

View File

@ -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>

View File

@ -27,7 +27,6 @@
#include "./Type.hpp"
#include "oatpp/core/base/memory/ObjectPool.hpp"
#include "oatpp/core/base/Countable.hpp"
#include <algorithm>

View File

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

View File

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

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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 {

View File

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

View File

@ -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() {

View File

@ -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;

View File

@ -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,

View File

@ -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 {

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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";

View File

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

View File

@ -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>

View File

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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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);

View File

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

View File

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

View File

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

View File

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

View File

@ -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());

View File

@ -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;

View File

@ -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();

View File

@ -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());