Renamed JsonBuffer to MemoryPool

This commit is contained in:
Benoit Blanchon
2018-09-03 16:14:21 +02:00
parent e5c4778ff7
commit 2998a55f0b
48 changed files with 365 additions and 361 deletions

View File

@ -0,0 +1,13 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(DynamicMemoryPoolTests
alloc.cpp
no_memory.cpp
size.cpp
startString.cpp
)
target_link_libraries(DynamicMemoryPoolTests catch)
add_test(DynamicMemoryPool DynamicMemoryPoolTests)

View File

@ -0,0 +1,77 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <sstream>
using namespace ArduinoJson::Internals;
static bool isAligned(void* ptr) {
const size_t mask = sizeof(void*) - 1;
size_t addr = reinterpret_cast<size_t>(ptr);
return (addr & mask) == 0;
}
std::stringstream allocatorLog;
struct SpyingAllocator : DefaultAllocator {
void* allocate(size_t n) {
allocatorLog << "A" << (n - DynamicMemoryPool::EmptyBlockSize);
return DefaultAllocator::allocate(n);
}
void deallocate(void* p) {
allocatorLog << "F";
return DefaultAllocator::deallocate(p);
}
};
TEST_CASE("DynamicMemoryPool::alloc()") {
SECTION("Returns different pointers") {
DynamicMemoryPool memoryPool;
void* p1 = memoryPool.alloc(1);
void* p2 = memoryPool.alloc(2);
REQUIRE(p1 != p2);
}
SECTION("Doubles allocation size when full") {
allocatorLog.str("");
{
DynamicMemoryPoolBase<SpyingAllocator> memoryPool(1);
memoryPool.alloc(1);
memoryPool.alloc(1);
}
REQUIRE(allocatorLog.str() == "A1A2FF");
}
SECTION("Resets allocation size after clear()") {
allocatorLog.str("");
{
DynamicMemoryPoolBase<SpyingAllocator> memoryPool(1);
memoryPool.alloc(1);
memoryPool.alloc(1);
memoryPool.clear();
memoryPool.alloc(1);
}
REQUIRE(allocatorLog.str() == "A1A2FFA1F");
}
SECTION("Makes a big allocation when needed") {
allocatorLog.str("");
{
DynamicMemoryPoolBase<SpyingAllocator> memoryPool(1);
memoryPool.alloc(42);
}
REQUIRE(allocatorLog.str() == "A42F");
}
SECTION("Alignment") {
// make room for two but not three
DynamicMemoryPool tinyBuf(2 * sizeof(void*) + 1);
REQUIRE(isAligned(tinyBuf.alloc(1))); // this on is aligned by design
REQUIRE(isAligned(tinyBuf.alloc(1))); // this one fits in the first block
REQUIRE(isAligned(tinyBuf.alloc(1))); // this one requires a new block
}
}

View File

@ -0,0 +1,41 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
struct NoMemoryAllocator {
void* allocate(size_t) {
return NULL;
}
void deallocate(void*) {}
};
TEST_CASE("DynamicMemoryPool no memory") {
DynamicMemoryPoolBase<NoMemoryAllocator> _memoryPool;
SECTION("FixCodeCoverage") {
// call this function to fix code coverage
NoMemoryAllocator().deallocate(NULL);
}
// TODO: uncomment
// SECTION("deserializeJson()") {
// char json[] = "{[]}";
// DynamicJsonDocument obj;
// DeserializationError err = deserializeJson(obj, json);
// REQUIRE(err != DeserializationError::Ok);
// }
SECTION("startString()") {
DynamicMemoryPoolBase<NoMemoryAllocator>::String str =
_memoryPool.startString();
str.append('!');
REQUIRE(0 == str.c_str());
}
}

View File

@ -0,0 +1,29 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson/Memory/DynamicMemoryPool.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("DynamicMemoryPool::size()") {
DynamicMemoryPool memoryPool;
SECTION("Initial size is 0") {
REQUIRE(0 == memoryPool.size());
}
SECTION("Increases after alloc()") {
memoryPool.alloc(1);
REQUIRE(1U <= memoryPool.size());
memoryPool.alloc(1);
REQUIRE(2U <= memoryPool.size());
}
SECTION("Goes back to 0 after clear()") {
memoryPool.alloc(1);
memoryPool.clear();
REQUIRE(0 == memoryPool.size());
}
}

View File

@ -0,0 +1,49 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson/Memory/DynamicMemoryPool.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("DynamicMemoryPool::startString()") {
SECTION("WorksWhenBufferIsBigEnough") {
DynamicMemoryPool memoryPool(6);
DynamicMemoryPool::String str = memoryPool.startString();
str.append('h');
str.append('e');
str.append('l');
str.append('l');
str.append('o');
REQUIRE(std::string("hello") == str.c_str());
}
SECTION("GrowsWhenBufferIsTooSmall") {
DynamicMemoryPool memoryPool(5);
DynamicMemoryPool::String str = memoryPool.startString();
str.append('h');
str.append('e');
str.append('l');
str.append('l');
str.append('o');
REQUIRE(std::string("hello") == str.c_str());
}
SECTION("SizeIncreases") {
DynamicMemoryPool memoryPool(5);
DynamicMemoryPool::String str = memoryPool.startString();
REQUIRE(0 == memoryPool.size());
str.append('h');
REQUIRE(1 == memoryPool.size());
str.c_str();
REQUIRE(2 == memoryPool.size());
}
}