allocString.cpp 3.7 KB

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