allocString.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // ArduinoJson - arduinojson.org
  2. // Copyright Benoit Blanchon 2014-2018
  3. // MIT License
  4. #include <ArduinoJson/Memory/StaticMemoryPool.hpp>
  5. #include <catch.hpp>
  6. using namespace ARDUINOJSON_NAMESPACE;
  7. TEST_CASE("StaticMemoryPool::allocFrozenString()") {
  8. const size_t poolCapacity = 64;
  9. const size_t longestString = poolCapacity - sizeof(StringSlot);
  10. StaticMemoryPool<poolCapacity> pool;
  11. SECTION("Returns different addresses") {
  12. StringSlot *a = pool.allocFrozenString(1);
  13. StringSlot *b = pool.allocFrozenString(1);
  14. REQUIRE(a != b);
  15. REQUIRE(a->value != b->value);
  16. }
  17. SECTION("Returns a StringSlot of the right size") {
  18. StringSlot *s = pool.allocFrozenString(12);
  19. REQUIRE(s->size == 12);
  20. }
  21. SECTION("Returns NULL when full") {
  22. pool.allocFrozenString(longestString);
  23. void *p = pool.allocFrozenString(1);
  24. REQUIRE(0 == p);
  25. }
  26. SECTION("Returns NULL when pool is too small") {
  27. void *p = pool.allocFrozenString(longestString + 1);
  28. REQUIRE(0 == p);
  29. }
  30. SECTION("Returns aligned pointers") {
  31. REQUIRE(isAligned(pool.allocFrozenString(1)));
  32. REQUIRE(isAligned(pool.allocFrozenString(1)));
  33. }
  34. SECTION("Returns same address after clear()") {
  35. StringSlot *a = pool.allocFrozenString(1);
  36. pool.clear();
  37. StringSlot *b = pool.allocFrozenString(1);
  38. REQUIRE(a == b);
  39. REQUIRE(a->value == b->value);
  40. }
  41. SECTION("Returns same address after freeString()") {
  42. StringSlot *a = pool.allocFrozenString(1);
  43. pool.freeString(a);
  44. StringSlot *b = pool.allocFrozenString(1);
  45. REQUIRE(a == b);
  46. REQUIRE(a->value == b->value);
  47. }
  48. SECTION("Can use full capacity when fresh") {
  49. StringSlot *a = pool.allocFrozenString(longestString);
  50. REQUIRE(a != 0);
  51. }
  52. SECTION("Can use full capacity after clear") {
  53. pool.allocFrozenString(longestString);
  54. pool.clear();
  55. StringSlot *a = pool.allocFrozenString(longestString);
  56. REQUIRE(a != 0);
  57. }
  58. }
  59. TEST_CASE("StaticMemoryPool::freeString()") {
  60. const size_t poolCapacity = 512;
  61. const size_t longestString = poolCapacity - sizeof(StringSlot);
  62. StaticMemoryPool<poolCapacity> pool;
  63. static const size_t testStringSize =
  64. (poolCapacity - sizeof(StringSlot) * 4 - sizeof(VariantSlot) * 4) / 4;
  65. SECTION("Restores full capacity") {
  66. StringSlot *strings[4];
  67. VariantSlot *variants[4];
  68. for (int i = 0; i < 4; i++) {
  69. strings[i] = pool.allocFrozenString(testStringSize);
  70. REQUIRE(strings[i] != 0);
  71. variants[i] = pool.allocVariant();
  72. REQUIRE(variants[i] != 0);
  73. }
  74. // In random order
  75. pool.freeString(strings[2]);
  76. pool.freeVariant(variants[3]);
  77. pool.freeVariant(variants[0]);
  78. pool.freeString(strings[0]);
  79. pool.freeVariant(variants[1]);
  80. pool.freeString(strings[1]);
  81. pool.freeVariant(variants[2]);
  82. pool.freeString(strings[3]);
  83. StringSlot *b = pool.allocFrozenString(longestString);
  84. REQUIRE(b != 0);
  85. REQUIRE(b->size == longestString);
  86. }
  87. SECTION("Move strings") {
  88. StringSlot *a = pool.allocFrozenString(6);
  89. strcpy(a->value, "hello");
  90. StringSlot *b = pool.allocFrozenString(7);
  91. strcpy(b->value, "world!");
  92. pool.freeString(a);
  93. REQUIRE(b->size == 7);
  94. REQUIRE(b->value == std::string("world!"));
  95. REQUIRE(a->value == b->value);
  96. }
  97. SECTION("Accepts non-frozen string") {
  98. StringSlot *a = pool.allocExpandableString();
  99. pool.freeString(a);
  100. REQUIRE(pool.size() == 0);
  101. }
  102. }