alloc.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // ArduinoJson - arduinojson.org
  2. // Copyright Benoit Blanchon 2014-2023
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. #include <sstream>
  7. using namespace ArduinoJson::Internals;
  8. static bool isAligned(void* ptr) {
  9. const size_t mask = sizeof(void*) - 1;
  10. size_t addr = reinterpret_cast<size_t>(ptr);
  11. return (addr & mask) == 0;
  12. }
  13. std::stringstream allocatorLog;
  14. struct SpyingAllocator : DefaultAllocator {
  15. void* allocate(size_t n) {
  16. allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize);
  17. return DefaultAllocator::allocate(n);
  18. }
  19. void deallocate(void* p) {
  20. allocatorLog << "F";
  21. return DefaultAllocator::deallocate(p);
  22. }
  23. };
  24. TEST_CASE("DynamicJsonBuffer::alloc()") {
  25. SECTION("Returns different pointers") {
  26. DynamicJsonBuffer buffer;
  27. void* p1 = buffer.alloc(1);
  28. void* p2 = buffer.alloc(2);
  29. REQUIRE(p1 != p2);
  30. }
  31. SECTION("Doubles allocation size when full") {
  32. allocatorLog.str("");
  33. {
  34. DynamicJsonBufferBase<SpyingAllocator> buffer(1);
  35. buffer.alloc(1);
  36. buffer.alloc(1);
  37. }
  38. REQUIRE(allocatorLog.str() == "A1A2FF");
  39. }
  40. SECTION("Resets allocation size after clear()") {
  41. allocatorLog.str("");
  42. {
  43. DynamicJsonBufferBase<SpyingAllocator> buffer(1);
  44. buffer.alloc(1);
  45. buffer.alloc(1);
  46. buffer.clear();
  47. buffer.alloc(1);
  48. }
  49. REQUIRE(allocatorLog.str() == "A1A2FFA1F");
  50. }
  51. SECTION("Makes a big allocation when needed") {
  52. allocatorLog.str("");
  53. {
  54. DynamicJsonBufferBase<SpyingAllocator> buffer(1);
  55. buffer.alloc(42);
  56. }
  57. REQUIRE(allocatorLog.str() == "A42F");
  58. }
  59. SECTION("Alignment") {
  60. // make room for two but not three
  61. DynamicJsonBuffer tinyBuf(2 * sizeof(void*) + 1);
  62. REQUIRE(isAligned(tinyBuf.alloc(1))); // this on is aligned by design
  63. REQUIRE(isAligned(tinyBuf.alloc(1))); // this one fits in the first block
  64. REQUIRE(isAligned(tinyBuf.alloc(1))); // this one requires a new block
  65. }
  66. }