Removed the indirection via StringSlot

This commit is contained in:
Benoit Blanchon
2018-11-27 17:28:19 +01:00
parent 45f4e5ac20
commit a60162ba76
23 changed files with 105 additions and 164 deletions

View File

@ -7,8 +7,8 @@ project(ArduinoJson)
enable_testing() enable_testing()
add_definitions(-DARDUINOJSON_DEBUG)
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
add_definitions(-DARDUINOJSON_DEBUG)
add_compile_options(-g -O0) add_compile_options(-g -O0)
endif() endif()

View File

@ -1,4 +1,6 @@
Version,Date,JsonParserExample,JsonGeneratorExample Version,Date,JsonParserExample,JsonGeneratorExample
v6.6.0-beta-6-g8217012,2018-11-27,7204,7630
v6.6.0-beta-5-g13cc610,2018-11-27,7264,7850
v6.6.0-beta-2-g2bd280d,2018-11-16,7872,8446 v6.6.0-beta-2-g2bd280d,2018-11-16,7872,8446
v6.6.0-beta,2018-11-13,8380,8916 v6.6.0-beta,2018-11-13,8380,8916
v6.5.0-beta,2018-10-13,7384,7874 v6.5.0-beta,2018-10-13,7384,7874

1 Version Date JsonParserExample JsonGeneratorExample
2 v6.6.0-beta-6-g8217012 2018-11-27 7204 7630
3 v6.6.0-beta-5-g13cc610 2018-11-27 7264 7850
4 v6.6.0-beta-2-g2bd280d 2018-11-16 7872 8446
5 v6.6.0-beta 2018-11-13 8380 8916
6 v6.5.0-beta 2018-10-13 7384 7874

View File

@ -48,8 +48,6 @@ union JsonVariantContent {
JsonArrayData asArray; JsonArrayData asArray;
JsonObjectData asObject; JsonObjectData asObject;
const char *asString; const char *asString;
struct StringSlot *asOwnedString;
struct StringSlot *asOwnedRaw;
struct { struct {
const char *data; const char *data;
size_t size; size_t size;

View File

@ -103,9 +103,9 @@ inline bool objectCopy(JsonObjectData* dst, const JsonObjectData* src,
for (VariantSlot* s = src->head; s; s = s->next) { for (VariantSlot* s = src->head; s; s = s->next) {
JsonVariantData* var; JsonVariantData* var;
if (s->value.keyIsOwned) if (s->value.keyIsOwned)
var = objectAdd(dst, ZeroTerminatedRamString(s->ownedKey->value), pool); var = objectAdd(dst, ZeroTerminatedRamString(s->key), pool);
else else
var = objectAdd(dst, ZeroTerminatedRamStringConst(s->linkedKey), pool); var = objectAdd(dst, ZeroTerminatedRamStringConst(s->key), pool);
if (!variantCopy(var, &s->value, pool)) return false; if (!variantCopy(var, &s->value, pool)) return false;
} }
return true; return true;

View File

@ -13,28 +13,28 @@ namespace ARDUINOJSON_NAMESPACE {
template <typename TKey> template <typename TKey>
inline bool slotSetKey(VariantSlot* var, TKey key, MemoryPool* pool) { inline bool slotSetKey(VariantSlot* var, TKey key, MemoryPool* pool) {
StringSlot* slot = key.save(pool); char* dup = key.save(pool);
if (!slot) return false; if (!dup) return false;
var->ownedKey = slot; var->key = dup;
var->value.keyIsOwned = true; var->value.keyIsOwned = true;
return true; return true;
} }
inline bool slotSetKey(VariantSlot* var, ZeroTerminatedRamStringConst key, inline bool slotSetKey(VariantSlot* var, ZeroTerminatedRamStringConst key,
MemoryPool*) { MemoryPool*) {
var->linkedKey = key.c_str(); var->key = key.c_str();
var->value.keyIsOwned = false; var->value.keyIsOwned = false;
return true; return true;
} }
inline bool slotSetKey(VariantSlot* var, StringInMemoryPool key, MemoryPool*) { inline bool slotSetKey(VariantSlot* var, StringInMemoryPool key, MemoryPool*) {
var->ownedKey = key.slot(); var->key = key.c_str();
var->value.keyIsOwned = true; var->value.keyIsOwned = true;
return true; return true;
} }
inline const char* slotGetKey(const VariantSlot* var) { inline const char* slotGetKey(const VariantSlot* var) {
return var->value.keyIsOwned ? var->ownedKey->value : var->linkedKey; return var->key;
} }
inline const VariantSlot* slotAdvance(const VariantSlot* var, size_t distance) { inline const VariantSlot* slotAdvance(const VariantSlot* var, size_t distance) {

View File

@ -22,9 +22,8 @@ inline T variantAsIntegral(const JsonVariantData* var) {
case JSON_NEGATIVE_INTEGER: case JSON_NEGATIVE_INTEGER:
return T(~var->content.asInteger + 1); return T(~var->content.asInteger + 1);
case JSON_LINKED_STRING: case JSON_LINKED_STRING:
return parseInteger<T>(var->content.asString);
case JSON_OWNED_STRING: case JSON_OWNED_STRING:
return parseInteger<T>(var->content.asOwnedString->value); return parseInteger<T>(var->content.asString);
case JSON_FLOAT: case JSON_FLOAT:
return T(var->content.asFloat); return T(var->content.asFloat);
default: default:
@ -47,9 +46,8 @@ inline T variantAsFloat(const JsonVariantData* var) {
case JSON_NEGATIVE_INTEGER: case JSON_NEGATIVE_INTEGER:
return -static_cast<T>(var->content.asInteger); return -static_cast<T>(var->content.asInteger);
case JSON_LINKED_STRING: case JSON_LINKED_STRING:
return parseFloat<T>(var->content.asString);
case JSON_OWNED_STRING: case JSON_OWNED_STRING:
return parseFloat<T>(var->content.asOwnedString->value); return parseFloat<T>(var->content.asString);
case JSON_FLOAT: case JSON_FLOAT:
return static_cast<T>(var->content.asFloat); return static_cast<T>(var->content.asFloat);
default: default:
@ -61,9 +59,8 @@ inline const char* variantAsString(const JsonVariantData* var) {
if (!var) return 0; if (!var) return 0;
switch (var->type) { switch (var->type) {
case JSON_LINKED_STRING: case JSON_LINKED_STRING:
return var->content.asString;
case JSON_OWNED_STRING: case JSON_OWNED_STRING:
return var->content.asOwnedString->value; return var->content.asString;
default: default:
return 0; return 0;
} }
@ -144,10 +141,11 @@ template <typename T>
inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value, inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value,
MemoryPool* pool) { MemoryPool* pool) {
if (!var) return false; if (!var) return false;
StringSlot* slot = makeString(value.data(), value.size()).save(pool); char* dup = makeString(value.data(), value.size()).save(pool);
if (slot) { if (dup) {
var->type = JSON_OWNED_RAW; var->type = JSON_OWNED_RAW;
var->content.asOwnedRaw = slot; var->content.asRaw.data = dup;
var->content.asRaw.size = value.size();
return true; return true;
} else { } else {
var->type = JSON_NULL; var->type = JSON_NULL;
@ -158,10 +156,10 @@ inline bool variantSetOwnedRaw(JsonVariantData* var, SerializedValue<T> value,
template <typename T> template <typename T>
inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) { inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
if (!var) return false; if (!var) return false;
StringSlot* slot = value.save(pool); char* dup = value.save(pool);
if (slot) { if (dup) {
var->type = JSON_OWNED_STRING; var->type = JSON_OWNED_STRING;
var->content.asOwnedString = slot; var->content.asString = dup;
return true; return true;
} else { } else {
var->type = JSON_NULL; var->type = JSON_NULL;
@ -169,10 +167,10 @@ inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
} }
} }
inline bool variantSetOwnedString(JsonVariantData* var, StringSlot* slot) { inline bool variantSetOwnedString(JsonVariantData* var, char* s) {
if (!var) return false; if (!var) return false;
var->type = JSON_OWNED_STRING; var->type = JSON_OWNED_STRING;
var->content.asOwnedString = slot; var->content.asString = s;
return true; return true;
} }
@ -218,12 +216,11 @@ inline bool variantCopy(JsonVariantData* dst, const JsonVariantData* src,
return objectCopy(variantToObject(dst), &src->content.asObject, pool); return objectCopy(variantToObject(dst), &src->content.asObject, pool);
case JSON_OWNED_STRING: case JSON_OWNED_STRING:
return variantSetString( return variantSetString(
dst, makeString(src->content.asOwnedString->value), pool); dst, ZeroTerminatedRamString(src->content.asString), pool);
case JSON_OWNED_RAW: case JSON_OWNED_RAW:
return variantSetOwnedRaw(dst, return variantSetOwnedRaw(
serialized(src->content.asOwnedRaw->value, dst, serialized(src->content.asRaw.data, src->content.asRaw.size),
src->content.asOwnedRaw->size), pool);
pool);
default: default:
// caution: don't override keyIsOwned // caution: don't override keyIsOwned
dst->type = src->type; dst->type = src->type;
@ -266,16 +263,15 @@ inline bool variantEquals(const JsonVariantData* a, const JsonVariantData* b) {
if (a->type != b->type) return false; if (a->type != b->type) return false;
switch (a->type) { switch (a->type) {
case JSON_LINKED_RAW:
case JSON_LINKED_STRING: case JSON_LINKED_STRING:
case JSON_OWNED_STRING:
return !strcmp(a->content.asString, b->content.asString); return !strcmp(a->content.asString, b->content.asString);
case JSON_LINKED_RAW:
case JSON_OWNED_RAW: case JSON_OWNED_RAW:
case JSON_OWNED_STRING: return a->content.asRaw.size == b->content.asRaw.size &&
return a->content.asOwnedString->size == b->content.asOwnedString->size && !memcmp(a->content.asRaw.data, b->content.asRaw.data,
!memcmp(a->content.asOwnedString->value, a->content.asRaw.size);
b->content.asOwnedString->value,
a->content.asOwnedString->size);
case JSON_BOOLEAN: case JSON_BOOLEAN:
case JSON_POSITIVE_INTEGER: case JSON_POSITIVE_INTEGER:

View File

@ -19,7 +19,7 @@ class JsonKey {
} }
bool isNull() const { bool isNull() const {
return _slot == 0 || _slot->linkedKey == 0; return _slot == 0 || _slot->key == 0;
} }
friend bool operator==(JsonKey lhs, const char* rhs) { friend bool operator==(JsonKey lhs, const char* rhs) {

View File

@ -206,7 +206,8 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
// for internal use only // for internal use only
FORCE_INLINE bool set(StringInMemoryPool value) const { FORCE_INLINE bool set(StringInMemoryPool value) const {
return variantSetOwnedString(_data, value.slot()); return variantSetOwnedString(_data,
value.save(_memoryPool)); // TODO: remove?
} }
FORCE_INLINE bool set(ZeroTerminatedRamStringConst value) const { FORCE_INLINE bool set(ZeroTerminatedRamStringConst value) const {
return variantSetString(_data, value.c_str()); return variantSetString(_data, value.c_str());

View File

@ -89,15 +89,10 @@ inline void JsonVariantConst::accept(Visitor& visitor) const {
return visitor.visitObject(JsonObjectConst(&_data->content.asObject)); return visitor.visitObject(JsonObjectConst(&_data->content.asObject));
case JSON_LINKED_STRING: case JSON_LINKED_STRING:
case JSON_OWNED_STRING:
return visitor.visitString(_data->content.asString); return visitor.visitString(_data->content.asString);
case JSON_OWNED_STRING:
return visitor.visitString(_data->content.asOwnedString->value);
case JSON_OWNED_RAW: case JSON_OWNED_RAW:
return visitor.visitRawJson(_data->content.asOwnedRaw->value,
_data->content.asOwnedRaw->size);
case JSON_LINKED_RAW: case JSON_LINKED_RAW:
return visitor.visitRawJson(_data->content.asRaw.data, return visitor.visitRawJson(_data->content.asRaw.data,
_data->content.asRaw.size); _data->content.asRaw.size);

View File

@ -23,21 +23,6 @@ namespace ARDUINOJSON_NAMESPACE {
// _left _right // _left _right
class MemoryPool { class MemoryPool {
class UpdateStringSlotAddress {
public:
UpdateStringSlotAddress(const char* address, size_t offset)
: _address(address), _offset(offset) {}
void operator()(StringSlot* slot) const {
ARDUINOJSON_ASSERT(slot != NULL);
if (slot->value > _address) slot->value -= _offset;
}
private:
const char* _address;
size_t _offset;
};
public: public:
MemoryPool(char* buf, size_t capa) MemoryPool(char* buf, size_t capa)
: _begin(buf), : _begin(buf),
@ -66,34 +51,26 @@ class MemoryPool {
return allocRight<VariantSlot>(); return allocRight<VariantSlot>();
} }
StringSlot* allocFrozenString(size_t n) { char* allocFrozenString(size_t n) {
StringSlot* s = allocStringSlot();
if (!s) return 0;
if (!canAlloc(n)) return 0; if (!canAlloc(n)) return 0;
char* s = _left;
s->value = _left;
s->size = n;
_left += n; _left += n;
checkInvariants(); checkInvariants();
return s; return s;
} }
StringSlot* allocExpandableString() { StringSlot allocExpandableString() {
StringSlot* s = allocStringSlot(); StringSlot s;
if (!s) return 0; s.value = _left;
s.size = size_t(_right - _left);
s->value = _left;
s->size = size_t(_right - _left);
_left = _right; _left = _right;
checkInvariants(); checkInvariants();
return s; return s;
} }
void freezeString(StringSlot* slot, size_t newSize) { void freezeString(StringSlot& s, size_t newSize) {
_left -= (slot->size - newSize); _left -= (s.size - newSize);
slot->size = newSize; s.size = newSize;
checkInvariants(); checkInvariants();
} }

View File

@ -26,28 +26,28 @@ class StringBuilder {
} }
void append(char c) { void append(char c) {
if (!_slot) return; if (!_slot.value) return;
if (_size >= _slot->size) { if (_size >= _slot.size) {
_slot = 0; _slot.value = 0;
return; return;
} }
_slot->value[_size++] = c; _slot.value[_size++] = c;
} }
StringType complete() { StringType complete() {
append('\0'); append('\0');
if (_slot) { if (_slot.value) {
_parent->freezeString(_slot, _size); _parent->freezeString(_slot, _size);
} }
return _slot; return _slot.value;
} }
private: private:
MemoryPool* _parent; MemoryPool* _parent;
size_t _size; size_t _size;
StringSlot* _slot; StringSlot _slot;
}; };
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

View File

@ -7,14 +7,12 @@
#include <stddef.h> // for size_t #include <stddef.h> // for size_t
#include "../Configuration.hpp" #include "../Configuration.hpp"
#define JSON_STRING_SIZE(SIZE) \ #define JSON_STRING_SIZE(SIZE) (SIZE)
(sizeof(ARDUINOJSON_NAMESPACE::StringSlot) + (SIZE))
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
struct StringSlot { struct StringSlot {
char *value; char *value;
size_t size; size_t size;
struct StringSlot *next;
}; };
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

View File

@ -12,10 +12,7 @@ struct VariantSlot {
JsonVariantData value; JsonVariantData value;
struct VariantSlot* next; struct VariantSlot* next;
struct VariantSlot* prev; struct VariantSlot* prev;
union { const char* key;
const char* linkedKey;
StringSlot* ownedKey;
};
}; };
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

View File

@ -12,13 +12,12 @@ class ArduinoString {
public: public:
ArduinoString(const ::String& str) : _str(&str) {} ArduinoString(const ::String& str) : _str(&str) {}
template <typename TMemoryPool> char* save(MemoryPool* memoryPool) const {
StringSlot* save(TMemoryPool* memoryPool) const {
if (isNull()) return NULL; if (isNull()) return NULL;
size_t n = _str->length() + 1; size_t n = _str->length() + 1;
StringSlot* slot = memoryPool->allocFrozenString(n); char* dup = memoryPool->allocFrozenString(n);
if (slot) memcpy(slot->value, _str->c_str(), n); if (dup) memcpy(dup, _str->c_str(), n);
return slot; return dup;
} }
bool isNull() const { bool isNull() const {

View File

@ -21,12 +21,11 @@ class FixedSizeFlashString {
return !_str; return !_str;
} }
template <typename TMemoryPool> char* save(MemoryPool* memoryPool) const {
StringSlot* save(TMemoryPool* memoryPool) const {
if (!_str) return NULL; if (!_str) return NULL;
StringSlot* slot = memoryPool->allocFrozenString(_size); char* dup = memoryPool->allocFrozenString(_size);
if (!slot) memcpy_P(slot->value, (const char*)_str, _size); if (!dup) memcpy_P(dup, (const char*)_str, _size);
return slot; return dup;
} }
size_t size() const { size_t size() const {

View File

@ -23,11 +23,11 @@ class FixedSizeRamString {
} }
template <typename TMemoryPool> template <typename TMemoryPool>
StringSlot* save(TMemoryPool* memoryPool) const { char* save(TMemoryPool* memoryPool) const {
if (!_str) return NULL; if (!_str) return NULL;
StringSlot* slot = memoryPool->allocFrozenString(_size); char* dup = memoryPool->allocFrozenString(_size);
if (slot) memcpy(slot->value, _str, _size); if (dup) memcpy(dup, _str, _size);
return slot; return dup;
} }
size_t size() const { size_t size() const {

View File

@ -12,12 +12,11 @@ class StlString {
public: public:
StlString(const std::string& str) : _str(&str) {} StlString(const std::string& str) : _str(&str) {}
template <typename TMemoryPool> char* save(MemoryPool* memoryPool) const {
StringSlot* save(TMemoryPool* memoryPool) const {
size_t n = _str->length() + 1; size_t n = _str->length() + 1;
StringSlot* slot = memoryPool->allocFrozenString(n); char* dup = memoryPool->allocFrozenString(n);
if (slot) memcpy(slot->value, _str->c_str(), n); if (dup) memcpy(dup, _str->c_str(), n);
return slot; return dup;
} }
bool isNull() const { bool isNull() const {

View File

@ -5,44 +5,35 @@
#pragma once #pragma once
#include <string.h> #include <string.h>
#include "../Memory/StringSlot.hpp" #include "../Memory/MemoryPool.hpp"
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
class StringInMemoryPool { class StringInMemoryPool {
public: public:
StringInMemoryPool(StringSlot* s = 0) : _slot(s) {} StringInMemoryPool(char* s = 0) : _value(s) {}
bool equals(const char* expected) const { bool equals(const char* expected) const {
if (!_slot) return expected == 0; if (!_value) return expected == 0;
const char* actual = _slot->value; const char* actual = _value;
if (actual == expected) return true; if (actual == expected) return true;
return strcmp(actual, expected) == 0; return strcmp(actual, expected) == 0;
} }
char* save(void*) {
return _value;
}
bool isNull() const { bool isNull() const {
return !_slot; return !_value;
}
template <typename TMemoryPool>
StringSlot* save(TMemoryPool*) const {
return _slot;
}
size_t size() const {
return _slot->size;
}
StringSlot* slot() const {
return _slot;
} }
const char* c_str() const { const char* c_str() const {
return _slot->value; return _value;
} }
protected: protected:
StringSlot* _slot; char* _value;
}; };
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

View File

@ -20,13 +20,12 @@ class ZeroTerminatedFlashString {
return !_str; return !_str;
} }
template <typename TMemoryPool> char* save(MemoryPool* memoryPool) const {
StringSlot* save(TMemoryPool* memoryPool) const {
if (!_str) return NULL; if (!_str) return NULL;
size_t n = size() + 1; // copy the terminator size_t n = size() + 1; // copy the terminator
StringSlot* slot = memoryPool->allocFrozenString(n); char* dup = memoryPool->allocFrozenString(n);
if (slot) memcpy_P(slot->value, reinterpret_cast<const char*>(_str), n); if (dup) memcpy_P(dup, reinterpret_cast<const char*>(_str), n);
return slot; return dup;
} }
size_t size() const { size_t size() const {

View File

@ -14,12 +14,12 @@ class ZeroTerminatedRamString : public ZeroTerminatedRamStringConst {
: ZeroTerminatedRamStringConst(str) {} : ZeroTerminatedRamStringConst(str) {}
template <typename TMemoryPool> template <typename TMemoryPool>
StringSlot* save(TMemoryPool* memoryPool) const { char* save(TMemoryPool* memoryPool) const {
if (!_str) return NULL; if (!_str) return NULL;
size_t n = size() + 1; size_t n = size() + 1;
StringSlot* slot = memoryPool->allocFrozenString(n); char* dup = memoryPool->allocFrozenString(n);
if (slot) memcpy(slot->value, _str, n); if (dup) memcpy(dup, _str, n);
return slot; return dup;
} }
}; };

View File

@ -79,12 +79,12 @@ TEST_CASE("JsonVariant with not enough memory") {
JsonVariant v = doc.to<JsonVariant>(); JsonVariant v = doc.to<JsonVariant>();
SECTION("std::string") { SECTION("std::string") {
v.set(std::string("hello")); v.set(std::string("hello world!!"));
REQUIRE(v.isNull()); REQUIRE(v.isNull());
} }
SECTION("Serialized<std::string>") { SECTION("Serialized<std::string>") {
v.set(serialized(std::string("hello"))); v.set(serialized(std::string("hello world!!")));
REQUIRE(v.isNull()); REQUIRE(v.isNull());
} }
} }

View File

@ -9,26 +9,22 @@ using namespace ARDUINOJSON_NAMESPACE;
TEST_CASE("MemoryPool::allocFrozenString()") { TEST_CASE("MemoryPool::allocFrozenString()") {
const size_t poolCapacity = 64; const size_t poolCapacity = 64;
const size_t longestString = poolCapacity - sizeof(StringSlot); const size_t longestString = poolCapacity;
char buffer[poolCapacity]; char buffer[poolCapacity];
MemoryPool pool(buffer, poolCapacity); MemoryPool pool(buffer, poolCapacity);
SECTION("Returns different addresses") { SECTION("Returns different addresses") {
StringSlot *a = pool.allocFrozenString(1); char *a = pool.allocFrozenString(1);
StringSlot *b = pool.allocFrozenString(1); char *b = pool.allocFrozenString(1);
REQUIRE(a != b); REQUIRE(a != b);
REQUIRE(a->value != b->value);
}
SECTION("Returns a StringSlot of the right size") {
StringSlot *s = pool.allocFrozenString(12);
REQUIRE(s->size == 12);
} }
SECTION("Returns NULL when full") { SECTION("Returns NULL when full") {
pool.allocFrozenString(longestString); void *p1 = pool.allocFrozenString(longestString);
void *p = pool.allocFrozenString(1); REQUIRE(p1 != 0);
REQUIRE(0 == p);
void *p2 = pool.allocFrozenString(1);
REQUIRE(p2 == 0);
} }
SECTION("Returns NULL when pool is too small") { SECTION("Returns NULL when pool is too small") {
@ -46,22 +42,16 @@ TEST_CASE("MemoryPool::allocFrozenString()") {
REQUIRE(0 == pool2.allocFrozenString(2)); REQUIRE(0 == pool2.allocFrozenString(2));
} }
SECTION("Returns aligned pointers") {
REQUIRE(isAligned(pool.allocFrozenString(1)));
REQUIRE(isAligned(pool.allocFrozenString(1)));
}
SECTION("Returns same address after clear()") { SECTION("Returns same address after clear()") {
StringSlot *a = pool.allocFrozenString(1); void *a = pool.allocFrozenString(1);
pool.clear(); pool.clear();
StringSlot *b = pool.allocFrozenString(1); void *b = pool.allocFrozenString(1);
REQUIRE(a == b); REQUIRE(a == b);
REQUIRE(a->value == b->value);
} }
SECTION("Can use full capacity when fresh") { SECTION("Can use full capacity when fresh") {
StringSlot *a = pool.allocFrozenString(longestString); void *a = pool.allocFrozenString(longestString);
REQUIRE(a != 0); REQUIRE(a != 0);
} }
@ -70,7 +60,7 @@ TEST_CASE("MemoryPool::allocFrozenString()") {
pool.allocFrozenString(longestString); pool.allocFrozenString(longestString);
pool.clear(); pool.clear();
StringSlot *a = pool.allocFrozenString(longestString); void *a = pool.allocFrozenString(longestString);
REQUIRE(a != 0); REQUIRE(a != 0);
} }

View File

@ -28,11 +28,11 @@ TEST_CASE("MemoryPool::size()") {
} }
SECTION("Decreases after freezeString()") { SECTION("Decreases after freezeString()") {
StringSlot* a = memoryPool.allocExpandableString(); StringSlot a = memoryPool.allocExpandableString();
memoryPool.freezeString(a, 1); memoryPool.freezeString(a, 1);
REQUIRE(memoryPool.size() == JSON_STRING_SIZE(1)); REQUIRE(memoryPool.size() == JSON_STRING_SIZE(1));
StringSlot* b = memoryPool.allocExpandableString(); StringSlot b = memoryPool.allocExpandableString();
memoryPool.freezeString(b, 1); memoryPool.freezeString(b, 1);
REQUIRE(memoryPool.size() == 2 * JSON_STRING_SIZE(1)); REQUIRE(memoryPool.size() == 2 * JSON_STRING_SIZE(1));
} }