mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added DynamicJsonBuffer::clear()
				
					
				
			This commit is contained in:
		| @@ -6,6 +6,7 @@ HEAD | ||||
|  | ||||
| * Made `JsonBuffer` non-copyable (PR #524 by @luisrayas3) | ||||
| * Added `StaticJsonBuffer::clear()` | ||||
| * Added `DynamicJsonBuffer::clear()` | ||||
|  | ||||
| v5.10.1 | ||||
| ------- | ||||
|   | ||||
| @@ -46,30 +46,35 @@ class DynamicJsonBufferBase | ||||
|   }; | ||||
|  | ||||
|  public: | ||||
|   enum { EmptyBlockSize = sizeof(EmptyBlock) }; | ||||
|  | ||||
|   DynamicJsonBufferBase(size_t initialSize = 256) | ||||
|       : _head(NULL), _nextBlockCapacity(initialSize) {} | ||||
|  | ||||
|   ~DynamicJsonBufferBase() { | ||||
|     Block* currentBlock = _head; | ||||
|  | ||||
|     while (currentBlock != NULL) { | ||||
|       Block* nextBlock = currentBlock->next; | ||||
|       _allocator.deallocate(currentBlock); | ||||
|       currentBlock = nextBlock; | ||||
|     } | ||||
|     freeAllBlocks(); | ||||
|   } | ||||
|  | ||||
|   // Gets the number of bytes occupied in the buffer | ||||
|   size_t size() const { | ||||
|     size_t total = 0; | ||||
|     for (const Block* b = _head; b; b = b->next) total += b->size; | ||||
|     return total; | ||||
|   } | ||||
|  | ||||
|   // Allocates the specified amount of bytes in the buffer | ||||
|   virtual void* alloc(size_t bytes) { | ||||
|     alignNextAlloc(); | ||||
|     return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes); | ||||
|   } | ||||
|  | ||||
|   // Resets the buffer. | ||||
|   // USE WITH CAUTION: this invalidates all previously allocated data | ||||
|   void clear() { | ||||
|     freeAllBlocks(); | ||||
|     _head = 0; | ||||
|   } | ||||
|  | ||||
|   class String { | ||||
|    public: | ||||
|     String(DynamicJsonBufferBase* parent) | ||||
| @@ -129,7 +134,7 @@ class DynamicJsonBufferBase | ||||
|   } | ||||
|  | ||||
|   bool addNewBlock(size_t capacity) { | ||||
|     size_t bytes = sizeof(EmptyBlock) + capacity; | ||||
|     size_t bytes = EmptyBlockSize + capacity; | ||||
|     Block* block = static_cast<Block*>(_allocator.allocate(bytes)); | ||||
|     if (block == NULL) return false; | ||||
|     block->capacity = capacity; | ||||
| @@ -139,6 +144,16 @@ class DynamicJsonBufferBase | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   void freeAllBlocks() { | ||||
|     Block* currentBlock = _head; | ||||
|  | ||||
|     while (currentBlock != NULL) { | ||||
|       Block* nextBlock = currentBlock->next; | ||||
|       _allocator.deallocate(currentBlock); | ||||
|       currentBlock = nextBlock; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   TAllocator _allocator; | ||||
|   Block* _head; | ||||
|   size_t _nextBlockCapacity; | ||||
|   | ||||
| @@ -71,7 +71,7 @@ class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> { | ||||
|     return doAlloc(bytes); | ||||
|   } | ||||
|  | ||||
|   // Resets the size to zero. | ||||
|   // Resets the buffer. | ||||
|   // USE WITH CAUTION: this invalidates all previously allocated data | ||||
|   void clear() { | ||||
|     _size = 0; | ||||
|   | ||||
| @@ -8,10 +8,11 @@ | ||||
| add_executable(DynamicJsonBufferTests  | ||||
| 	alloc.cpp | ||||
| 	createArray.cpp | ||||
| 	no_memory.cpp | ||||
| 	createObject.cpp | ||||
| 	strdup.cpp | ||||
| 	no_memory.cpp | ||||
| 	size.cpp | ||||
| 	startString.cpp | ||||
| 	strdup.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(DynamicJsonBufferTests catch) | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <sstream> | ||||
|  | ||||
| static bool isAligned(void* ptr) { | ||||
|   const size_t mask = sizeof(void*) - 1; | ||||
| @@ -14,26 +15,58 @@ static bool isAligned(void* ptr) { | ||||
|   return (addr & mask) == 0; | ||||
| } | ||||
|  | ||||
| std::stringstream allocatorLog; | ||||
|  | ||||
| struct SpyingAllocator : DefaultAllocator { | ||||
|   void* allocate(size_t n) { | ||||
|     allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize); | ||||
|     return DefaultAllocator::allocate(n); | ||||
|   } | ||||
|   void deallocate(void* p) { | ||||
|     allocatorLog << "F"; | ||||
|     return DefaultAllocator::deallocate(p); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| TEST_CASE("DynamicJsonBuffer::alloc()") { | ||||
|   DynamicJsonBuffer buffer; | ||||
|  | ||||
|   SECTION("InitialSizeIsZero") { | ||||
|     REQUIRE(0 == buffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("SizeIncreasesAfterAlloc") { | ||||
|     buffer.alloc(1); | ||||
|     REQUIRE(1U <= buffer.size()); | ||||
|     buffer.alloc(1); | ||||
|     REQUIRE(2U <= buffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("ReturnDifferentPointer") { | ||||
|   SECTION("Returns different pointers") { | ||||
|     DynamicJsonBuffer buffer; | ||||
|     void* p1 = buffer.alloc(1); | ||||
|     void* p2 = buffer.alloc(2); | ||||
|     REQUIRE(p1 != p2); | ||||
|   } | ||||
|  | ||||
|   SECTION("Doubles allocation size when full") { | ||||
|     allocatorLog.str(""); | ||||
|     { | ||||
|       DynamicJsonBufferBase<SpyingAllocator> buffer(1); | ||||
|       buffer.alloc(1); | ||||
|       buffer.alloc(1); | ||||
|     } | ||||
|     REQUIRE(allocatorLog.str() == "A1A2FF"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Keeps increasing allocation size after clear") { | ||||
|     allocatorLog.str(""); | ||||
|     { | ||||
|       DynamicJsonBufferBase<SpyingAllocator> buffer(1); | ||||
|       buffer.alloc(1); | ||||
|       buffer.alloc(1); | ||||
|       buffer.clear(); | ||||
|       buffer.alloc(1); | ||||
|     } | ||||
|     REQUIRE(allocatorLog.str() == "A1A2FFA4F"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Makes a big allocation when needed") { | ||||
|     allocatorLog.str(""); | ||||
|     { | ||||
|       DynamicJsonBufferBase<SpyingAllocator> buffer(1); | ||||
|       buffer.alloc(42); | ||||
|     } | ||||
|     REQUIRE(allocatorLog.str() == "A42F"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Alignment") { | ||||
|     // make room for two but not three | ||||
|     DynamicJsonBuffer tinyBuf(2 * sizeof(void*) + 1); | ||||
|   | ||||
							
								
								
									
										30
									
								
								test/DynamicJsonBuffer/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								test/DynamicJsonBuffer/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| // Copyright Benoit Blanchon 2014-2017 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://bblanchon.github.io/ArduinoJson/ | ||||
| // If you like this project, please add a star! | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("DynamicJsonBuffer::size()") { | ||||
|   DynamicJsonBuffer buffer; | ||||
|  | ||||
|   SECTION("Initial size is 0") { | ||||
|     REQUIRE(0 == buffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Increases after alloc()") { | ||||
|     buffer.alloc(1); | ||||
|     REQUIRE(1U <= buffer.size()); | ||||
|     buffer.alloc(1); | ||||
|     REQUIRE(2U <= buffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Goes back to 0 after clear()") { | ||||
|     buffer.alloc(1); | ||||
|     buffer.clear(); | ||||
|     REQUIRE(0 == buffer.size()); | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user