forked from bblanchon/ArduinoJson
Test extension slot allocation failure
This commit is contained in:
@ -188,12 +188,12 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("int64_t") {
|
SECTION("int64_t") {
|
||||||
bool result = variant.set(int64_t(-2147483649));
|
bool result = variant.set(int64_t(-2147483649LL));
|
||||||
doc.shrinkToFit();
|
doc.shrinkToFit();
|
||||||
|
|
||||||
REQUIRE(result == true);
|
REQUIRE(result == true);
|
||||||
REQUIRE(variant.is<int64_t>() == true);
|
REQUIRE(variant.is<int64_t>() == true);
|
||||||
REQUIRE(variant.as<int64_t>() == -2147483649);
|
REQUIRE(variant.as<int64_t>() == -2147483649LL);
|
||||||
REQUIRE(spy.log() ==
|
REQUIRE(spy.log() ==
|
||||||
AllocatorLog{
|
AllocatorLog{
|
||||||
Allocate(sizeofPool()),
|
Allocate(sizeofPool()),
|
||||||
@ -278,6 +278,34 @@ TEST_CASE("JsonVariant::set() with not enough memory") {
|
|||||||
REQUIRE(result == false);
|
REQUIRE(result == false);
|
||||||
REQUIRE(v.isNull());
|
REQUIRE(v.isNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("int32_t") {
|
||||||
|
bool result = v.set(-42);
|
||||||
|
|
||||||
|
REQUIRE(result == true);
|
||||||
|
REQUIRE(v.is<int32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int64_t") {
|
||||||
|
bool result = v.set(-2147483649LL);
|
||||||
|
|
||||||
|
REQUIRE(result == false);
|
||||||
|
REQUIRE(v.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("uint32_t") {
|
||||||
|
bool result = v.set(42);
|
||||||
|
|
||||||
|
REQUIRE(result == true);
|
||||||
|
REQUIRE(v.is<uint32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("uint64_t") {
|
||||||
|
bool result = v.set(4294967296U);
|
||||||
|
|
||||||
|
REQUIRE(result == false);
|
||||||
|
REQUIRE(v.isNull());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("JsonVariant::set() releases the previous value") {
|
TEST_CASE("JsonVariant::set() releases the previous value") {
|
||||||
@ -325,29 +353,33 @@ TEST_CASE("JsonVariant::set() releases the previous value") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Extension slots") {
|
TEST_CASE("JsonVariant::set() reuses extension slot") {
|
||||||
SpyingAllocator spy;
|
SpyingAllocator spy;
|
||||||
JsonDocument doc(&spy);
|
JsonDocument doc(&spy);
|
||||||
|
JsonVariant variant = doc.to<JsonVariant>();
|
||||||
|
|
||||||
SECTION("double requires two slot") {
|
variant.set(1.2);
|
||||||
int i = ARDUINOJSON_POOL_CAPACITY - 1;
|
doc.shrinkToFit();
|
||||||
|
spy.clearLog();
|
||||||
|
|
||||||
// make sure the pool is full
|
SECTION("double") {
|
||||||
doc[i] = 1;
|
bool result = variant.set(3.4);
|
||||||
REQUIRE(spy.log() == AllocatorLog{
|
|
||||||
Allocate(sizeofPool()),
|
|
||||||
});
|
|
||||||
|
|
||||||
// replace with a float => no allocation
|
REQUIRE(result == true);
|
||||||
spy.clearLog();
|
|
||||||
doc[i] = 1.2f;
|
|
||||||
REQUIRE(spy.log() == AllocatorLog{});
|
REQUIRE(spy.log() == AllocatorLog{});
|
||||||
|
}
|
||||||
|
|
||||||
// replace with a double => new pool needed
|
SECTION("int64_t") {
|
||||||
spy.clearLog();
|
bool result = variant.set(-2147483649LL);
|
||||||
doc[i] = 1.2;
|
|
||||||
REQUIRE(spy.log() == AllocatorLog{
|
REQUIRE(result == true);
|
||||||
Allocate(sizeofPool()),
|
REQUIRE(spy.log() == AllocatorLog{});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
SECTION("uint64_t") {
|
||||||
|
bool result = variant.set(4294967296U);
|
||||||
|
|
||||||
|
REQUIRE(result == true);
|
||||||
|
REQUIRE(spy.log() == AllocatorLog{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,8 +65,7 @@ struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
|
|||||||
return false;
|
return false;
|
||||||
auto resources = getResourceManager(dst);
|
auto resources = getResourceManager(dst);
|
||||||
data->clear(resources);
|
data->clear(resources);
|
||||||
data->setInteger(src, resources);
|
return data->setInteger(src, resources);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static T fromJson(JsonVariantConst src) {
|
static T fromJson(JsonVariantConst src) {
|
||||||
|
@ -427,12 +427,12 @@ class VariantData {
|
|||||||
enable_if_t<sizeof(T) == 8, bool> setFloat(T value, ResourceManager*);
|
enable_if_t<sizeof(T) == 8, bool> setFloat(T value, ResourceManager*);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
enable_if_t<is_signed<T>::value> setInteger(T value,
|
enable_if_t<is_signed<T>::value, bool> setInteger(T value,
|
||||||
ResourceManager* resources);
|
ResourceManager* resources);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
enable_if_t<is_unsigned<T>::value> setInteger(T value,
|
enable_if_t<is_unsigned<T>::value, bool> setInteger(
|
||||||
ResourceManager* resources);
|
T value, ResourceManager* resources);
|
||||||
|
|
||||||
void setRawString(StringNode* s) {
|
void setRawString(StringNode* s) {
|
||||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||||
|
@ -92,7 +92,7 @@ enable_if_t<sizeof(T) == 8, bool> VariantData::setFloat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
enable_if_t<is_signed<T>::value> VariantData::setInteger(
|
enable_if_t<is_signed<T>::value, bool> VariantData::setInteger(
|
||||||
T value, ResourceManager* resources) {
|
T value, ResourceManager* resources) {
|
||||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
@ -104,17 +104,18 @@ enable_if_t<is_signed<T>::value> VariantData::setInteger(
|
|||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
else {
|
else {
|
||||||
auto extension = resources->allocExtension();
|
auto extension = resources->allocExtension();
|
||||||
if (extension) {
|
if (!extension)
|
||||||
type_ = VALUE_IS_INT64;
|
return false;
|
||||||
content_.asSlotId = extension.id();
|
type_ = VALUE_IS_INT64;
|
||||||
extension->asInt64 = value;
|
content_.asSlotId = extension.id();
|
||||||
}
|
extension->asInt64 = value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
enable_if_t<is_unsigned<T>::value> VariantData::setInteger(
|
enable_if_t<is_unsigned<T>::value, bool> VariantData::setInteger(
|
||||||
T value, ResourceManager* resources) {
|
T value, ResourceManager* resources) {
|
||||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
@ -126,13 +127,14 @@ enable_if_t<is_unsigned<T>::value> VariantData::setInteger(
|
|||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
else {
|
else {
|
||||||
auto extension = resources->allocExtension();
|
auto extension = resources->allocExtension();
|
||||||
if (extension) {
|
if (!extension)
|
||||||
type_ = VALUE_IS_UINT64;
|
return false;
|
||||||
content_.asSlotId = extension.id();
|
type_ = VALUE_IS_UINT64;
|
||||||
extension->asUint64 = value;
|
content_.asSlotId = extension.id();
|
||||||
}
|
extension->asUint64 = value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user